Tree n points M bar (in fact, n-1) q a query
A1 A2 A3 ...
The people who started these nodes
I a b c a->b this chain is all plus C
D... Reducing
Q A queries the person on Node A
Look at the comments on the code
#include <stdio.h>#include<string.h>#include<algorithm>using namespacestd;#defineMAXN 50010structedge{intTo,w,next;} x[2*MAXN];intHEAD[MAXN];intNUM[MAXN],SIZ[MAXN], TOP[MAXN], SON[MAXN],DEP[MAXN],TID[MAXN];int_TID[MAXN],FATHER[MAXN];
Right includes this tree node number tree chain head heavy child depth tree chain subscript
/According to the tree of the line segment L find this point, father.
intCnt,n,m,q,tim;voidAddintUintv)//Build side {x[cnt].to=v; X[cnt].next=Head[u]; Head[u]=cnt++;}voidInitintN) {CNT=0; Tim=0; memset (Head,-1,sizeof(head)); memset (son,0,sizeof(son));voidDFS1 (intUintFA) {Siz[u]=1;//The number of nodes that include the sub-tree of this point father[u]=FA; Dep[u]=dep[fa]+1; for(inti=head[u];i!=-1; i=X[i].next) { intv=x[i].to; if(v==FA)Continue; DFS1 (V,u); Siz[u]+=Siz[v]; if(Siz[son[u]) <Siz[v])//Find heavy children son[u]=v; }}voidDFS2 (intUintTp//{Tid[u]=++tim;//L r _tid[tim in line segment tree]=u;//in turn top[u]=TP;//head of chainif(son[u]!=0)//On a chain of lines on a continuous part of the segment Tree DFS2 (SON[U],TP); for(inti=head[u];i!=-1; i=X[i].next) { intv=x[i].to; if(v!=father[u]&&v!=Son[u])//Neither father nor heavy child re-planing sub-DFS2 (V,V); }}structnode{intL,r,val,lazy;} Z[MAXN<<3];voidUpdateintLintRintA1,intB1,intVinta);voidChangeintXintYintval) { while(top[x]!=Top[y]) { if(dep[top[x]]<Dep[top[y]]) swap (x, y); Update (1, N,tid[top[x]],tid[x],val,1);//link header to this node update x=Father[top[x]]; } if(Dep[x] >Dep[y]) swap (x, y); Update (1, N,tid[x],tid[y],val,1); Last}voidBuildintLintRinta) {Z[A].L=l; Z[A].R=R; Z[a].val=z[a].lazy=0; if(l==r) {Z[a].val=Num[_tid[l]]; return ; } intMid= (l+r) >>1; Build (L,mid,a<<1); Build (Mid+1,r,a<<1|1);}voidPush_down (inta) { if(z[a].lazy) {z[a<<1].val+=Z[a].lazy; Z[a<<1|1].val+=Z[a].lazy; Z[a<<1].lazy+=Z[a].lazy; Z[a<<1|1].lazy+=Z[a].lazy; Z[a].lazy=0; }}voidUpdateintLintRintA1,intB1,intVinta) { if(a1<=l&&r<=B1) {Z[a].val+=v; Z[a].lazy+=v; return ; } push_down (a); intMid= (l+r) >>1; if(a1<=mid) Update (L,mid,a1,b1,v,a<<1); if(b1>mid) Update (mid+1,r,a1,b1,v,a<<1|1);}intQues (intLintRintXinta) {Push_down (a); if(l==r&&l==x)returnZ[a].val; intMid= (l+r) >>1; if(x<=mid)returnQues (l,mid,x,a<<1); Else returnQues (mid+1,r,x,a<<1|1);}intMain () { while(SCANF ("%d%d%d", &n,&m,&q)! =EOF) {init (n); for(intI=1; i<=n;i++) scanf ("%d",&Num[i]); while(m--) { intu,v; scanf ("%d%d",&u,&v); Add (U,V); Add (V,u); } DFS1 (1,0);//2 deep search DFS2 (1,1); Build (1N1);//Achievements while(q--) { Chars[5]; scanf ("%s", s); if(s[0]=='Q') { intA; scanf ("%d",&a); printf ("%d\n", Ques (1, N,tid[a],1)); } Else { intA,b,c; scanf ("%d%d%d",&a,&b,&c); if(s[0]=='I') Change (A,B,C); ElseChange (A, B,-c); } } } return 0;}
Tree-chain Planing Division HDU 3966