結果

問題 No.3113 The farthest point
ユーザー hato336
提出日時 2025-04-18 21:22:32
言語 PyPy3
(7.3.15)
結果
TLE  
実行時間 -
コード長 8,047 bytes
コンパイル時間 527 ms
コンパイル使用メモリ 82,188 KB
実行使用メモリ 181,176 KB
最終ジャッジ日時 2025-04-18 21:23:19
合計ジャッジ時間 41,719 ms
ジャッジサーバーID
(参考情報)
judge2 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 25 TLE * 8
権限があれば一括ダウンロードができます

ソースコード

diff #

#https://github.com/shakayami/ACL-for-python/blob/master/lazysegtree.py
class lazy_segtree():
    def update(self,k):self.d[k]=self.op(self.d[2*k],self.d[2*k+1])
    def all_apply(self,k,f):
        self.d[k]=self.mapping(f,self.d[k])
        if (k<self.size):self.lz[k]=self.composition(f,self.lz[k])
    def push(self,k):
        self.all_apply(2*k,self.lz[k])
        self.all_apply(2*k+1,self.lz[k])
        self.lz[k]=self.identity
    def __init__(self,V,OP,E,MAPPING,COMPOSITION,ID):
        self.n=len(V)
        self.log=(self.n-1).bit_length()
        self.size=1<<self.log
        self.d=[E for i in range(2*self.size)]
        self.lz=[ID for i in range(self.size)]
        self.e=E
        self.op=OP
        self.mapping=MAPPING
        self.composition=COMPOSITION
        self.identity=ID
        for i in range(self.n):self.d[self.size+i]=V[i]
        for i in range(self.size-1,0,-1):self.update(i)
    def set(self,p,x):
        assert 0<=p and p<self.n
        p+=self.size
        for i in range(self.log,0,-1):self.push(p>>i)
        self.d[p]=x
        for i in range(1,self.log+1):self.update(p>>i)
    def get(self,p):
        assert 0<=p and p<self.n
        p+=self.size
        for i in range(self.log,0,-1):self.push(p>>i)
        return self.d[p]
    def prod(self,l,r):
        assert 0<=l and l<=r and r<=self.n
        if l==r:return self.e
        l+=self.size
        r+=self.size
        for i in range(self.log,0,-1):
            if (((l>>i)<<i)!=l):self.push(l>>i)
            if (((r>>i)<<i)!=r):self.push(r>>i)
        sml,smr=self.e,self.e
        while(l<r):
            if l&1:
                sml=self.op(sml,self.d[l])
                l+=1
            if r&1:
                r-=1
                smr=self.op(self.d[r],smr)
            l>>=1
            r>>=1
        return self.op(sml,smr)
    def all_prod(self):return self.d[1]
    def apply_point(self,p,f):
        assert 0<=p and p<self.n
        p+=self.size
        for i in range(self.log,0,-1):self.push(p>>i)
        self.d[p]=self.mapping(f,self.d[p])
        for i in range(1,self.log+1):self.update(p>>i)
    def apply(self,l,r,f):
        assert 0<=l and l<=r and r<=self.n
        if l==r:return
        l+=self.size
        r+=self.size
        for i in range(self.log,0,-1):
            if (((l>>i)<<i)!=l):self.push(l>>i)
            if (((r>>i)<<i)!=r):self.push((r-1)>>i)
        l2,r2=l,r
        while(l<r):
            if (l&1):
                self.all_apply(l,f)
                l+=1
            if (r&1):
                r-=1
                self.all_apply(r,f)
            l>>=1
            r>>=1
        l,r=l2,r2
        for i in range(1,self.log+1):
            if (((l>>i)<<i)!=l):self.update(l>>i)
            if (((r>>i)<<i)!=r):self.update((r-1)>>i)
    def max_right(self,l,g):
        assert 0<=l and l<=self.n
        assert g(self.e)
        if l==self.n:return self.n
        l+=self.size
        for i in range(self.log,0,-1):self.push(l>>i)
        sm=self.e
        while(1):
            while(l%2==0):l>>=1
            if not(g(self.op(sm,self.d[l]))):
                while(l<self.size):
                    self.push(l)
                    l=(2*l)
                    if (g(self.op(sm,self.d[l]))):
                        sm=self.op(sm,self.d[l])
                        l+=1
                return l-self.size
            sm=self.op(sm,self.d[l])
            l+=1
            if (l&-l)==l:break
        return self.n
    def min_left(self,r,g):
        assert (0<=r and r<=self.n)
        assert g(self.e)
        if r==0:return 0
        r+=self.size
        for i in range(self.log,0,-1):self.push((r-1)>>i)
        sm=self.e
        while(1):
            r-=1
            while(r>1 and (r%2)):r>>=1
            if not(g(self.op(self.d[r],sm))):
                while(r<self.size):
                    self.push(r)
                    r=(2*r+1)
                    if g(self.op(self.d[r],sm)):
                        sm=self.op(self.d[r],sm)
                        r-=1
                return r+1-self.size
            sm=self.op(self.d[r],sm)
            if (r&-r)==r:break
        return 0
mod = 998244353
#区間加算・区間最小値取得 lst = lazy_segtree([],min,10**18,operator.add,operator.add,0)
#区間加算・区間最大値取得 lst = lazy_segtree([],max,-10**18,operator.add,operator.add,0)
#区間加算・区間和取得 lst = lazy_segtree([(alist[i],1) for i in range(n)],lambda x,y:((x[0]+y[0])%mod,x[1]+y[1]),(0,0),lambda x,y:((y[0]+x*y[1])%mod,y[1]),operator.add,0)
#区間変更・区間最小値取得 lst = lazy_segtree([],min,10**18,lambda x,y:y if x == 10**18 else x,lambda x,y:y if x == 10**18 else x,10**18)
#区間変更・区間最大値取得 lst = lazy_segtree([],max,-10**18,lambda x,y:y if x == -10**18 else x,lambda x,y:y if x == -10**18 else x,-10**18)
#区間変更・区間和取得 lst = lazy_segtree([(alist[i],1) for i in range(n)],lambda x,y:((x[0]+y[0])%mod,x[1]+y[1]),(0,0),lambda x,y:(y[1]*x,y[1]) if x != 10**18 else y,lambda x,y:y if x == 10**18 else x,10**18)

def op(x,y):
    return
#xはlazy, yはd
def mapping(x,y):
    return
#yが作用してからxが作用する
def composition(x,y):
    return
import sys
input = sys.stdin.readline
n1 = int(input())
edge1 = [[] for i in range(n1)]
import collections
cc = collections.defaultdict(int)
for i in range(n1-1):
    u,v,w = map(int,input().split())
    u-=1
    v-=1
    edge1[u].append(v)
    edge1[v].append(u)
    cc[u*n1+v] = w
    cc[v*n1+u] = w


import bisect
class Vertex_Add_Subtree_Sum():
    def __init__(self,n,edge):
        self.n = n
        self.edge = edge
        P = [-1] * n
        Q = [~0,0]
        ct = -1
        ET = []
        ET1 = [0] * n
        ET2 = [0] * n
        DE = [0] * n
        de = -1
        while Q:
            i = Q.pop()
            if i < 0:
                # ↓ 戻りも数字を足す場合はこれを使う
                ct += 1
                # ↓ 戻りもETに入れる場合はこれを使う
                ET.append(i)
                ET2[~i] = ct
                de -= 1
                continue
            if i >= 0:
                ET.append(i)
                ct += 1
                if ET1[i] == 0: ET1[i] = ct
                de += 1
                DE[i] = de
            for a in self.edge[i][::-1]:
                if a != P[i]:
                    P[a] = i
                    for k in range(len(self.edge[a])):
                        if self.edge[a][k] == i:
                            del self.edge[a][k]
                            break
                    Q.append(~a)
                    Q.append(a)
        self.et = ET
        self.et1 = ET1
        self.et2 = ET2
        self.et_sorted = list(sorted(self.et1))

        self.l = list(range(n))
        self.l.sort(key=lambda x:self.et1[x])
    def subtree(self,x):
        left,right = self.et1[x],self.et2[x]
        left = bisect.bisect_left(self.et_sorted,left)
        right = bisect.bisect_left(self.et_sorted,right)
        return left,right
import collections,heapq
start = 0
d = collections.deque()
dist = [10**18 for i in range(n1)]
d.append(start)
dist[start] = 0
dist2 = [0 for i in range(n1)]
p = [-1 for i in range(n1)]
while d:
    now = d.popleft()
    for i in edge1[now]:
        if dist[i] > dist[now] + 1:
            dist[i] = dist[now] + 1
            d.append(i)
            p[i] = now
            dist2[i] = dist2[now] + cc[i*n1+now]

import operator
v1 = Vertex_Add_Subtree_Sum(n1,edge1)
lst1 = lazy_segtree([dist2[i] for i in v1.l],max,-10**18,operator.add,operator.add,0)

a = [-1 for i in range(n1)]
l0,r0 = v1.subtree(0)
#print(v1.et)
for i in v1.et:
    if i >= 0:
        if i != 0:
            cost = cc[p[i]*n1+i]
            l,r = v1.subtree(i)
            lst1.apply(l,r,-2 * cost)
            lst1.apply(l0,r0,1 * cost)
        a[i] = lst1.all_prod()

    if i < 0:
        j = ~i
        cost = cc[p[j]*n1+j]
        l,r = v1.subtree(j)
        lst1.apply(l,r,2 * cost)
        lst1.apply(l0,r0,-1 * cost)
print(max(a))
0