QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#790250#5418. Color the TreevwxyzTL 2193ms21000kbPython316.9kb2024-11-28 09:05:152024-11-28 09:05:15

Judging History

你现在查看的是最新测评结果

  • [2024-11-28 09:05:15]
  • 评测
  • 测评结果:TL
  • 用时:2193ms
  • 内存:21000kb
  • [2024-11-28 09:05:15]
  • 提交

answer

class Graph:
    def __init__(self,V,edges=None,graph=None,directed=False,weighted=False,inf=float("inf")):
        self.V=V
        self.directed=directed
        self.weighted=weighted
        self.inf=inf
        if graph!=None:
            self.graph=graph
            """
            self.edges=[]
            for i in range(self.V):
                if self.weighted:
                    for j,d in self.graph[i]:
                        if self.directed or not self.directed and i<=j:
                            self.edges.append((i,j,d))
                else:
                    for j in self.graph[i]:
                        if self.directed or not self.directed and i<=j:
                            self.edges.append((i,j))
            """
        else:
            self.edges=edges
            self.graph=[[] for i in range(self.V)]
            if weighted:
                for i,j,d in self.edges:
                    self.graph[i].append((j,d))
                    if not self.directed:
                        self.graph[j].append((i,d))
            else:
                for i,j in self.edges:
                    self.graph[i].append(j)
                    if not self.directed:
                        self.graph[j].append(i)

    def Build_LCA(self,s,segment_tree=False):
        self.lca_segment_tree=segment_tree
        if self.lca_segment_tree:
            self.lca_euler_tour,self.lca_parents,depth=self.SIV_DFS(s,euler_tour=True,parents=True,unweighted_dist=True)
            self.lca_dfs_in_index=[None]*self.V
            self.lca_dfs_out_index=[None]*self.V
            for i,x in enumerate(self.lca_euler_tour):
                if x>=0:
                    self.lca_dfs_in_index[x]=i
                else:
                    self.lca_dfs_out_index[~x]=i
            self.ST=Segment_Tree(2*self.V,min,self.V)
            lst=[None]*(2*self.V)
            for i in range(2*self.V-1):
                if self.lca_euler_tour[i]>=0:
                    lst[i]=depth[self.lca_euler_tour[i]]
                else:
                    lst[i]=depth[self.lca_parents[~self.lca_euler_tour[i]]]
            lst[2*self.V-1]=-1
            self.ST.Build(lst)
        else:
            self.lca_parents,self.lca_depth=self.SIV_DFS(s,parents=True,unweighted_dist=True)
            self.lca_PD=Path_Doubling(self.V,self.lca_parents)
            self.lca_PD.Build_Next(self.V)

    def LCA(self,a,b):
        if self.lca_segment_tree:
            m=min(self.lca_dfs_in_index[a],self.lca_dfs_in_index[b])
            M=max(self.lca_dfs_in_index[a],self.lca_dfs_in_index[b])
            x=self.lca_euler_tour[self.ST.Fold_Index(m,M+1)]
            if x>=0:
                lca=x
            else:
                lca=self.lca_parents[~x]
        else:
            if self.lca_depth[a]>self.lca_depth[b]:
                a,b=b,a
            b=self.lca_PD.Doubling_Permutation(b,self.lca_depth[b]-self.lca_depth[a])
            if a!=b:
                for k in range(self.lca_PD.k-1,-1,-1):
                    if self.lca_PD.doubling_permutation[k][a]!=self.lca_PD.doubling_permutation[k][b]:
                        a,b=self.lca_PD.doubling_permutation[k][a],self.lca_PD.doubling_permutation[k][b]
                a,b=self.lca_PD.doubling_permutation[0][a],self.lca_PD.doubling_permutation[0][b]
            lca=a
        return lca

    def Build_Auxiliary_Tree(self,s):
        self.Build_LCA(s,segment_tree=True)
        self.auxiliary_tree_use=[False]*self.V

    def Auxiliary_Tree(self,points):
        points=sorted(list(set(points)),key=lambda x:self.lca_dfs_in_index[x])
        for x in points:
            self.auxiliary_tree_use[x]=True
        le=len(points)
        for i in range(le-1):
            lca=self.LCA(points[i],points[i+1])
            if not self.auxiliary_tree_use[lca]:
                points.append(lca)
                self.auxiliary_tree_use[lca]=True
        points.sort(key=lambda x:self.lca_dfs_in_index[x])
        le=len(points)
        parents=[None]*le
        stack=[]
        for i in range(le):
            while stack and self.lca_dfs_out_index[points[stack[-1]]]<self.lca_dfs_in_index[points[i]]:
                stack.pop()
            if stack:
                parents[i]=stack[-1]
            stack.append(i)
        for x in points:
            self.auxiliary_tree_use[x]=False
        return parents,points

    def SIV_DFS(self,s,bipartite_graph=False,cycle_detection=False,directed_acyclic=False,euler_tour=False,linked_components=False,lowlink=False,parents=False,postorder=False,preorder=False,subtree_size=False,topological_sort=False,unweighted_dist=False,weighted_dist=False):
        seen=[False]*self.V
        finished=[False]*self.V
        if directed_acyclic or cycle_detection or topological_sort:
            dag=True
        if euler_tour:
            et=[]
        if linked_components:
            lc=[]
        if lowlink:
            order=[None]*self.V
            ll=[None]*self.V
            idx=0
        if parents or cycle_detection or lowlink or subtree_size:
            ps=[None]*self.V
        if postorder or topological_sort:
            post=[]
        if preorder:
            pre=[]
        if subtree_size:
            ss=[1]*self.V
        if unweighted_dist or bipartite_graph:
            uwd=[self.inf]*self.V
            uwd[s]=0
        if weighted_dist:
            wd=[self.inf]*self.V
            wd[s]=0
        stack=[(s,0)] if self.weighted else [s]
        while stack:
            if self.weighted:
                x,d=stack.pop()
            else:
                x=stack.pop()
            if not seen[x]:
                seen[x]=True
                stack.append((x,d) if self.weighted else x)
                if euler_tour:
                    et.append(x)
                if linked_components:
                    lc.append(x)
                if lowlink:
                    order[x]=idx
                    ll[x]=idx
                    idx+=1
                if preorder:
                    pre.append(x)
                for y in self.graph[x]:
                    if self.weighted:
                        y,d=y
                    if not seen[y]:
                        stack.append((y,d) if self.weighted else y)
                        if parents or cycle_detection or lowlink or subtree_size:
                            ps[y]=x
                        if unweighted_dist or bipartite_graph:
                            uwd[y]=uwd[x]+1
                        if weighted_dist:
                            wd[y]=wd[x]+d
                    elif not finished[y]:
                        if (directed_acyclic or cycle_detection or topological_sort) and dag:
                            dag=False
                            if cycle_detection:
                                cd=(y,x)
            elif not finished[x]:
                finished[x]=True
                if euler_tour:
                    et.append(~x)
                if lowlink:
                    bl=True
                    for y in self.graph[x]:
                        if self.weighted:
                            y,d=y
                        if ps[x]==y and bl:
                            bl=False
                            continue
                        ll[x]=min(ll[x],order[y])
                    if x!=s:
                        ll[ps[x]]=min(ll[ps[x]],ll[x])
                if postorder or topological_sort:
                    post.append(x)
                if subtree_size:
                    for y in self.graph[x]:
                        if self.weighted:
                            y,d=y
                        if y==ps[x]:
                            continue
                        ss[x]+=ss[y]
        if bipartite_graph:
            bg=[[],[]]
            for tpl in self.edges:
                x,y=tpl[:2] if self.weighted else tpl
                if uwd[x]==self.inf or uwd[y]==self.inf:
                    continue
                if not uwd[x]%2^uwd[y]%2:
                    bg=False
                    break
            else:
                for x in range(self.V):
                    if uwd[x]==self.inf:
                        continue
                    bg[uwd[x]%2].append(x)
        retu=()
        if bipartite_graph:
            retu+=(bg,)
        if cycle_detection:
            if dag:
                cd=[]
            else:
                y,x=cd
                cd=self.Route_Restoration(y,x,ps)
            retu+=(cd,)
        if directed_acyclic:
            retu+=(dag,)
        if euler_tour:
            retu+=(et,)
        if linked_components:
            retu+=(lc,)
        if lowlink:
            retu=(ll,)
        if parents:
            retu+=(ps,)
        if postorder:
            retu+=(post,)
        if preorder:
            retu+=(pre,)
        if subtree_size:
            retu+=(ss,)
        if topological_sort:
            if dag:
                tp_sort=post[::-1]
            else:
                tp_sort=[]
            retu+=(tp_sort,)
        if unweighted_dist:
            retu+=(uwd,)
        if weighted_dist:
            retu+=(wd,)
        if len(retu)==1:
            retu=retu[0]
        return retu
from collections import defaultdict

class Segment_Tree:
    def __init__(self,N,f,e,lst=None,dynamic=False,bisect_search=True):
        self.f=f
        self.e=e
        self.N=N
        self.bisect_search=bisect_search
        if self.bisect_search:
            self.le=1
            while self.le<self.N:
                self.le*=2
        else:
            self.le=self.N
        if dynamic:
            self.segment_tree=defaultdict(lambda:self.e)
        else:
            if lst==None:
                self.segment_tree=[self.e]*2*self.le
            else:
                assert len(lst)<=self.N
                self.segment_tree=[self.e]*self.le+[x for x in lst]+[self.e]*(self.le-len(lst))
                for i in range(self.le-1,0,-1):
                    self.segment_tree[i]=self.f(self.segment_tree[i<<1],self.segment_tree[i<<1|1])

    def __getitem__(self,i):
        if type(i)==int:
            if -self.le<=i<0:
                return self.segment_tree[i+self.le*2]
            elif 0<=i<self.le:
                return self.segment_tree[i+self.le]
            else:
                raise IndexError("list index out of range")
        else:
            a,b,c=i.start,i.stop,i.step
            if a==None:
                a=self.le
            else:
                a+=self.le
            if b==None:
                b=self.le*2
            else:
                b+=self.le
            return self.segment_tree[slice(a,b,c)]

    def __setitem__(self,i,x):
        if -self.le<=i<0:
            i+=self.le*2
        elif 0<=i<self.le:
            i+=self.le
        else:
            raise IndexError("list index out of range")
        self.segment_tree[i]=x
        while i>1:
            i>>= 1
            self.segment_tree[i]=self.f(self.segment_tree[i<<1],self.segment_tree[i<<1|1])

    def Build(self,lst):
        for i,x in enumerate(lst,self.le):
            self.segment_tree[i]=x
        for i in range(self.le-1,0,-1):
            self.segment_tree[i]=self.f(self.segment_tree[i<<1],self.segment_tree[i<<1|1])

    def Fold(self,L=None,R=None):
        if L==None:
            L=self.le
        else:
            assert 0<=L<=self.N
            L+=self.le
        if R==None:
            R=self.le*2
        else:
            assert 0<=R<=self.N
            R+=self.le
        vL=self.e
        vR=self.e
        while L<R:
            if L&1:
                vL=self.f(vL,self.segment_tree[L])
                L+=1
            if R&1:
                R-=1
                vR=self.f(self.segment_tree[R],vR)
            L>>=1
            R>>=1
        return self.f(vL,vR)

    def Fold_Index(self,L=None,R=None):
        if L==None:
            L=self.le
        else:
            assert 0<=L<=self.N
            L+=self.le
        if R==None:
            R=self.le*2
        else:
            assert 0<=R<=self.N
            R+=self.le
        if L==R:
            return None
        x=self.Fold(L-self.le,R-self.le)
        while L<R:
            if L&1:
                if self.segment_tree[L]==x:
                    i=L
                    break
                L+=1
            if R&1:
                R-=1
                if self.segment_tree[R]==x:
                    i=R
                    break
            L>>=1
            R>>=1
        while i<self.le:
            if self.segment_tree[i]==self.segment_tree[i<<1]:
                i<<=1
            else:
                i<<=1
                i|=1
        i-=self.le
        return i

    def Bisect_Right(self,L=None,f=None):
        assert self.bisect_search
        if L==self.le:
            return self.le
        if L==None:
            L=0
        assert 0<=L<=self.N
        L+=self.le
        vl=self.e
        vr=self.e
        l,r=L,self.le*2
        while l<r:
            if l&1:
                vl=self.f(vl,self.segment_tree[l])
                l+=1
            if r&1:
                r-=1
                vr=self.f(self.segment_tree[r],vr)
            l>>=1
            r>>=1
        if f(self.f(vl,vr)):
            return self.N
        v=self.e
        while True:
            while L%2==0:
                L>>=1
            vv=self.f(v,self.segment_tree[L])
            if f(vv):
                v=vv
                L+=1
            else:
                while L<self.le:
                    L<<=1
                    vv=self.f(v,self.segment_tree[L])
                    if f(vv):
                        v=vv
                        L+=1
                return L-self.le

    def Bisect_Left(self,R=None,f=None):
        assert self.bisect_search
        if R==0:
            return 0
        if R==None:
            R=self.le
        assert 0<=R<=self.N
        R+=self.le
        vl=self.e
        vr=self.e
        l,r=self.le,R
        while l<r:
            if l&1:
                vl=self.f(vl,self.segment_tree[l])
                l+=1
            if r&1:
                r-=1
                vr=self.f(self.segment_tree[r],vr)
            l>>=1
            r>>=1
        if f(self.f(vl,vr)):
            return 0
        v=self.e
        while True:
            R-=1
            while R>1 and R%2:
                R>>=1
            vv=self.f(self.segment_tree[R],v)
            if f(vv):
                v=vv
            else:
                while R<self.le:
                    R=2*R+1
                    vv=self.f(self.segment_tree[R],v)
                    if f(vv):
                        v=vv
                        R-=1
                return R+1-self.le

    def __str__(self):
        return "["+", ".join(map(str,[self.segment_tree[i] for i in range(self.le,self.le+self.N)]))+"]"

    def __repr__(self):
        return "Segment_Tree("+str(self)+")"
class Sparse_Table:
    def __init__(self,N,f,e,lst):
        self.N=N
        self.f=f
        self.e=e
        self.n=N.bit_length()
        self.dp=[[None]*(self.N-(1<<n)+1) for n in range(self.n)]
        if self.n:
            for i in range(self.N):
                self.dp[0][i]=lst[i]
            for n in range(1,self.n):
                for i in range(self.N-(1<<n)+1):
                    self.dp[n][i]=self.f(self.dp[n-1][i],self.dp[n-1][i+(1<<n-1)])

    def Fold(self,L=None,R=None):
        if L==None:
            L=0
        if R==None:
            R=self.N
        if L==R:
            return self.e
        n=(R-L).bit_length()-1
        return self.f(self.dp[n][L],self.dp[n][R-(1<<n)])

T=int(input())
for t in range(T):
    N=int(input())
    A=list(map(int,input().split()))
    inf=1<<30
    ST=Sparse_Table(N,min,inf,A)
    graph=[[] for x in range(N)]
    for m in range(N-1):
        u,v=map(int,input().split())
        u-=1;v-=1
        graph[u].append(v)
        graph[v].append(u)
    G=Graph(N,graph=graph)
    G.Build_Auxiliary_Tree(0)
    depth=G.SIV_DFS(0,unweighted_dist=True)
    ans=0
    idx=[[0] for d in range(N)]
    for x in range(N):
        idx[depth[x]].append(x)
    for d in range(N):
        parents,P=G.Auxiliary_Tree(idx[d])
        le=len(parents)
        cnt=[0]*le
        for p in parents:
            if p!=None:
                cnt[p]+=1
        queue=[x for x in range(le) if cnt[x]==0]
        dp=[0]*le
        while queue:
            x=queue.pop()
            if depth[P[x]]==d:
                dp[x]=A[0]
            dp[x]=min(dp[x],ST.Fold(d-depth[P[x]],d+1))
            if parents[x]!=None:
                dp[parents[x]]+=dp[x]
                cnt[parents[x]]-=1
                if cnt[parents[x]]==0:
                    queue.append(parents[x])
        if le:
            ans+=dp[parents.index(None)]
    print(ans)

詳細信息

Test #1:

score: 100
Accepted
time: 16ms
memory: 10748kb

input:

3
4
10 15 40 1
1 2
2 3
2 4
5
10 5 1 100 1000
1 2
2 3
2 4
4 5
4
1000 200 10 8
1 2
2 3
3 4

output:

35
17
1218

result:

ok 3 number(s): "35 17 1218"

Test #2:

score: 0
Accepted
time: 1400ms
memory: 10856kb

input:

3000
54
43 44 11 49 17 14 7 30 35 12 34 14 15 8 29 47 30 31 39 17 26 23 26 45 34 50 49 13 35 18 29 15 13 44 47 5 22 20 19 46 30 22 26 13 47 46 43 27 48 48 13 14 30 44
1 2
1 3
2 4
3 5
4 6
2 7
4 8
1 9
3 10
1 11
8 12
2 13
9 14
1 15
1 16
15 17
15 18
7 19
1 20
19 21
13 22
10 23
17 24
9 25
9 26
24 27
8 28...

output:

180
168
222
230
156
240
225
126
100
81
155
73
154
127
149
124
228
230
132
187
153
170
78
282
195
286
191
211
119
197
211
233
88
252
239
233
173
180
195
121
109
148
180
175
226
210
182
97
199
59
56
31
115
204
203
172
139
208
53
140
189
170
173
137
233
94
163
273
80
350
156
133
146
159
240
269
137
222...

result:

ok 3000 numbers

Test #3:

score: 0
Accepted
time: 1500ms
memory: 11564kb

input:

300
474
5 24 21 41 15 23 43 48 32 19 27 40 10 49 40 6 18 41 43 31 45 18 35 36 12 10 23 45 28 23 14 43 37 45 12 16 20 17 49 13 22 8 30 19 27 40 22 14 30 47 16 39 25 48 21 26 50 8 14 26 9 30 41 15 44 24 16 46 50 39 25 47 24 45 21 18 26 21 5 39 15 10 47 48 11 44 44 33 23 14 35 39 35 30 38 9 13 15 39 5 ...

output:

329
183
264
219
323
220
348
342
410
395
80
201
299
144
207
408
360
215
283
104
320
394
277
210
273
285
242
253
265
379
360
322
202
351
195
196
266
270
171
342
239
283
286
300
331
317
345
268
173
296
275
224
480
330
264
162
199
378
254
214
231
293
229
259
241
268
380
419
233
185
364
341
328
237
320
3...

result:

ok 300 numbers

Test #4:

score: 0
Accepted
time: 1787ms
memory: 19660kb

input:

30
4926
18 13 47 7 21 39 28 48 21 44 14 18 39 13 46 33 6 49 9 7 10 29 29 25 38 15 16 42 41 41 40 14 26 13 6 19 17 31 24 18 30 24 48 46 38 21 28 42 29 50 33 28 18 26 18 42 13 23 35 20 32 6 17 25 44 46 35 36 50 24 7 29 34 14 41 41 8 33 22 46 7 6 22 40 24 8 44 36 38 13 37 37 25 22 7 43 50 33 19 44 24 4...

output:

427
520
443
359
427
408
371
415
482
436
269
530
478
485
435
453
418
503
443
453
405
425
347
564
297
435
559
453
213
395

result:

ok 30 numbers

Test #5:

score: 0
Accepted
time: 1443ms
memory: 10852kb

input:

3000
74
555233197 518812085 998593787 821753058 967306600 663279435 696954042 885219300 489323226 146136486 447383587 785317885 838306349 708275482 715157265 298848995 400280904 374077023 673881523 207667786 885945020 459791675 992519779 327830583 821713695 253985403 926395863 419409783 138881726 80...

output:

6742611216
5794349776
3087356867
4707144715
2761702533
3246645261
4802134565
2999820393
4887036613
2784978973
3593730307
4783057633
4621084176
4331196830
4242984461
2287799528
3027767371
3699192818
3888960419
6398323452
2766114996
1734720583
6543430036
1955540148
5464479116
3177069662
5145942113
302...

result:

ok 3000 numbers

Test #6:

score: 0
Accepted
time: 1598ms
memory: 11760kb

input:

300
621
259262308 372414267 976777900 567821544 262206094 972740633 932600104 702535786 494092920 919901107 797100568 708295156 632473907 101958470 952065075 970482879 183543308 323078517 719011818 352232578 159576652 124505381 125133768 492132730 331846050 577415810 369370004 871034176 529186574 44...

output:

8143086197
8197999468
5370721620
5343127707
5868323006
7992625789
5749423188
5019336842
5319894438
5228239187
5391752908
6084605805
6792215852
6057910407
8471127525
2719747215
6909535671
5100581420
5878004843
5586237425
6343902433
9390109727
5651124389
5472179570
7945151774
5064107530
4433748186
571...

result:

ok 300 numbers

Test #7:

score: 0
Accepted
time: 1553ms
memory: 17780kb

input:

30
5308
560111855 290003681 946208440 140658046 860834453 480249720 506770353 922783074 600720525 693059141 436061359 545671168 528534807 339705109 831632761 570564203 113225613 578123930 293066534 269996029 765346927 443717770 933144287 856263710 475170893 174188152 464281143 864607591 443380284 12...

output:

8829755982
7996435040
9259425768
7684533044
9842457103
3917213508
5939555066
8695995697
9431906955
7466353560
8322921019
8970732656
8099619221
9390765699
6773331885
8521621715
9998520099
7876760589
6482847050
10167157889
8563826262
5569616375
7783052317
7313404561
7224267995
8986870714
9082031438
99...

result:

ok 30 numbers

Test #8:

score: 0
Accepted
time: 2193ms
memory: 21000kb

input:

30
235
99 26 36 76 38 12 81 57 32 53 24 100 83 36 73 40 99 67 25 59 13 53 26 96 88 91 70 75 50 28 43 91 28 80 21 10 28 96 81 46 93 48 47 65 16 51 39 13 17 68 87 47 11 53 35 59 95 17 12 28 42 72 69 93 10 99 55 36 17 10 17 82 46 47 30 13 33 46 47 82 26 70 89 11 84 15 75 82 23 15 26 21 33 100 80 68 59 ...

output:

1853
53585
70793
41175
65095
19429
62735
44418
35618
52989
22194
74287
66783
60324
23354
10188
45849
43317
47709
44425
17639
2392
67454
75522
52049
63546
17778
37186
1857
31275

result:

ok 30 numbers

Test #9:

score: -100
Time Limit Exceeded

input:

3
99260
99 92 50 79 91 45 21 68 66 95 60 65 65 45 85 36 33 49 93 97 17 80 84 82 53 62 68 77 54 84 19 75 37 54 64 80 88 60 26 31 73 14 50 19 31 91 28 49 49 92 98 41 30 21 42 83 51 79 48 51 41 10 73 83 61 43 51 95 80 19 46 45 43 62 86 52 62 100 22 98 25 67 76 59 55 42 76 18 17 63 38 92 73 22 58 93 65 ...

output:

745947
689647

result: