http://acm.hdu.edu.cn/showproblem.php?pid=5692
This question really is to see the problem also engaged in a day, the next step after each route to re-label the 1-n, store each point in which paths appear (L and r Array), and then converted into a segment tree to update and take the maximum value.
Note that if you use recursion to build a line tree, the array must be 4n in order to ensure that it is not super.
The newly updated function updates all subtrees every time, then times out, and then adds an add to the tree, preserving the amount that the subtree needs to increase, and if this subtree is used, it is simply ingenious to add up the amount.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#defineINF 0x3f3f3f3f#pragmaComment (linker, "/stack:1024000000,1024000000")using namespaceStd;vector<int> line[100005];intn,m,cnt,l[100005],r[100005];Long Longw[100005],init[100005];structsegtree{intLeft,right; Long LongMaxx,add;} tree[400005];voidDfsintNowintPreLong Longsum) {Sum+=W[now]; intFlag =1; L[now]=INF; for(inti =0; i < line[now].size (); i++) { intNext =Line[now][i]; if(next = = Pre)Continue; Flag=0; DFS (next,now,sum); L[now]=min (L[now],l[next]); } init[cnt]=sum; R[now]= cnt++; if(flag) L[now] =R[now];}voidBuildintPosintLintR) {Tree[pos].left=l; Tree[pos].right=R; Tree[pos].add=0; if(L = = r) Tree[pos].maxx =Init[l]; Else { intMid = (l+r)/2; Build (POS*2, L,mid); Build (POS*2+1, mid+1, R); Tree[pos].maxx= Max (tree[pos*2].maxx,tree[pos*2+1].maxx); }}voidUpdateintPosintLintRLong Longv) { if(Tree[pos].add! =0) { if(Tree[pos].left! =tree[pos].right) {Tree[pos*2].maxx + =Tree[pos].add; Tree[pos*2].add + =Tree[pos].add; Tree[pos*2+1].maxx + =Tree[pos].add; Tree[pos*2+1].add + =Tree[pos].add; Tree[pos].add=0; } } if(Tree[pos].left = =L&& r = =tree[pos].right) {Tree[pos].maxx+=v; Tree[pos].add+=v; return; } intMid = (tree[pos].left+tree[pos].right)/2; if(R <= Mid) update (pos*2, l,r,v); Else if(L > Mid) Update (pos*2+1, l,r,v); Else{update (pos*2, l,mid,v); Update (POS*2+1, mid+1, r,v); } Tree[pos].maxx= Max (tree[pos*2].maxx,tree[pos*2+1].maxx);}Long LongGetmax (intPosintLintR) { if(Tree[pos].add! =0) { if(Tree[pos].left! =tree[pos].right) {Tree[pos*2].maxx + =Tree[pos].add; Tree[pos*2].add + =Tree[pos].add; Tree[pos*2+1].maxx + =Tree[pos].add; Tree[pos*2+1].add + =Tree[pos].add; Tree[pos].add=0; } } if(Tree[pos].left = = L && r = = tree[pos].right)returnTree[pos].maxx; intMid = (tree[pos].left+tree[pos].right)/2; if(R <= Mid)returnGetmax (pos*2, L,r); if(L > Mid)returnGetmax (pos*2+1, L,r); returnMax (Getmax (pos*2, L,mid), Getmax (pos*2+1, mid+1, R));}intMain () {intT; scanf ("%d",&T); for(intz =1; Z <= t;z++) {printf ("Case #%d:\n", z); scanf ("%d%d",&n,&m); for(inti =0; I < n;i++) line[i].clear (); for(inti =0; i < n-1; i++) { intx, y; scanf ("%d%d",&x,&y); Line[x].push_back (y); Line[y].push_back (x); } for(inti =0; i < n;i++) scanf ("%lld",&W[i]); CNT=1; DFS (0,0,0); Build (1,1, N); while(m--) { intop; scanf ("%d",&op); if(OP = =0) { intx, y; scanf ("%d%d",&x,&y); Long Longtemp = yW[x]; W[X]=y; Update (1, l[x],r[x],temp); } Else { intx; scanf ("%d",&x); printf ("%lld\n", Getmax (1, l[x],r[x])); } } } return 0;}
Hdu_5692_dfs sequence + segment tree