Title Link: http://www.lydsy.com/JudgeOnline/problem.php?id=1036
Test instructions: A tree, each node has a weighted value. Three operations: (1) Modify the weights of a node, (2) output the sum of the weights between a two nodes, and (3) output the maximum value of the weights between a two nodes.
Idea: (1) First, a father is recorded in Splay, which represents the parent node of the current node. But here, in a tree chain, the meaning of father and father in Splay is the same, that is, the father of V is U, then the left child of U or the right child must have a V. However, if V and U are not in a tree chain, then u represents the parent node of the topmost vertex of the tree chain where V is located. That is when you left child and right child are not v,u and V belong to two tree chain;
(2) The left child of V in a tree chain is the vertex above V, which is the parent node of V and the ancestor node in the original tree, and the right child is the vertex below V, the child of V in the original tree and the descendant node. Of course, whether the right child or the left child is present and V in a tree chain;
(3) splay (x) rotates x to the root of the tree chain where x is located, and access (x) turns the edge of X and root (the root is the true root) into a solid edge. In Access (x), the first thing to do is to break the association of X with its right child XR (in (4) We explain why to disconnect) and set the father of XR to X, then the XR will be the root of a tree chain, and then for V's parent node U, because you want to change the right child of U to V, So before U's right child (if any) ur is going to disconnect and set the father of Ur to u, then ur will be the root of the tree chain where you are, then set U's right child to V. Keep up until Root;
(4) For each calculation (x, y), the maximum or the first and the same time, access (×) to the edge between x and Root into a solid edge, and then access (Y) at this time the return value is P=lca (x, y). Think about why this is so? Because LCA (x, y) has been linked to X on a tree, because we already have access (x). Now when looking up from Y, for its father node Z, first splay Z will go to the root of its tree chain, and if Z is LCA (x, y), then Z will inevitably become a root, that is, root, then its Father node is null. Now we're clear. The return value is the LCA (x, y). Then P will be disconnected from X because x is below the right child or right child of P, and P's right child will turn to Y so it is disconnected. At this point, if Splay (x), then x is the root of the tree chain consisting of p to X path (without p), and does not contain the following parts of X, and in (3) We know that x goes up to access and the right child is disconnected. Then sum of x to Y can be calculated by sum of X and Val of P and the right child of P, which is Y.
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <cmath>5#include <string>6#include <algorithm>7 Long Longw[60005],sum[60005],mx[60005];8 intfa[60005],ch[60005][2],st[60005];9 intu[200005],v[200005],n,m,rev[60005],x,y;Ten voidUpdata (intx) { One intl=ch[x][0],r=ch[x][1]; Asum[x]=w[x]+sum[l]+Sum[r]; -mx[x]=Std::max (W[x],std::max (mx[l],mx[r)); - } the voidPushdown (intx) { - intl=ch[x][0],r=ch[x][1]; - if(Rev[x]) { -rev[x]^=1; +rev[l]^=1; -rev[r]^=1; +Std::swap (ch[x][1],ch[x][0]); A } at } - BOOLPdintx) { - returnch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; - } - voidRotateintx) { - inty=fa[x],z=Fa[y],l,r; in if(ch[y][0]==X) l=0;ElseL=1; r=l^1; - if(!PD (Y)) { to if(ch[z][0]==y) ch[z][0]=x;Elsech[z][1]=x; + } -fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; thech[y][l]=ch[x][r];ch[x][r]=y; * Updata (y); Updata (x); $ }Panax Notoginseng voidSplay (intx) { - inttop=0; st[++top]=x; the for(inti=x;! PD (i); i=Fa[i]) { +st[++top]=Fa[i]; A } the for(inti=top;i;i--) + pushdown (St[i]); - while(!PD (x)) { $ inty=fa[x],z=Fa[y]; $ if(!PD (Y)) { - if(ch[y][0]==x^ch[z][0]==y) rotate (x); - Elserotate (y); the } - rotate (x);Wuyi } the } - voidAccessintx) { Wu for(intt=0; x;t=x,x=Fa[x]) { - splay (x); Aboutch[x][1]=T; $ updata (x); - } - } - voidMakeroot (intx) { AAccess (x); splay (x); rev[x]^=1; + } the voidLinkintXinty) { - makeroot (x); $fa[x]=y; the } the intMain () { thescanf"%d", &n); mx[0]=-0x7fffffff; the for(intI=1; i<n;i++){ -scanf"%d%d",&u[i],&v[i]); in } the for(intI=1; i<=n;i++){ thescanf"%lld",&w[i]); Aboutsum[i]=mx[i]=W[i]; the } the for(intI=1; i<n;i++){ the link (u[i],v[i]); + } -scanf"%d",&m); the Chars[ -];Bayi for(intI=1; i<=m;i++){ thescanf"%s%d%d",s,&x,&y); the if(s[1]=='H'){ - splay (x); -w[x]=y; the updata (x); the } the Else the if(s[1]=='M'){ - makeroot (x); the access (y); the splay (y); theprintf"%lld\n", Mx[y]);94 } the Else{ the makeroot (x); the access (y);98 splay (y); Aboutprintf"%lld\n", Sum[y]); - }101 }102 103}
Bzoj 1036 [ZJOI2008] Tree statistics count (dynamic tree)