"title" #58. "WC2013" Candy Park
"Test Instructions" given n points of the tree, m kinds of candies, each point has candy ci. Given n number of WI and M number VI, the value of the nth tasting of the first candy is V (i) *w (j). Q Times ask for a link on the value of each point and or modify a point of candy ci. N,m,q<=10^5.
"Algorithm" tree chunking + with modified MO team algorithm
Reference:WC 2013 Candy Park vfleaking
First the tree is divided, referring to the method of the Royal Commonwealth. Make sure that the block size is B, and that DFS can be divided into blocks of size [b,3b], where the property is two points within a block of up to B.
The definition (x,y,t) asks for the answer to the X-y of the tree chain that has been modified by the T, and will ask the sort: first keyword belong[x], the second keyword Belong[y], and the third keyword T.
For a query, consider transferring from the last query (x ', y ', t '). First transfer T, only need to record each time before and after the modified values, you can implement the modification or inverse modification.
Then the tree chain X '-y ' is transferred to the tree chain XY, which requires XOR or operation (symmetry difference). The so-called XOR operation is that if X is marked, subtract the answer and eliminate the tag, add the answer and add the tag if x is not marked.
The specific process can be referred to VFK formula derivation, perceptual understanding is also very simple: define t (x, y) to indicate that in addition to the LCA (x, y) of the tree chain X-y, then t (x, y ') = t (x,x ') .
With this, we just have to differ on the current basis or the T (x,x ') and T (Y,y ') can be achieved from X ' Y ' transfer to X-y, of course, all of the LCA can be counted separately.
Also, if the value of point x is modified before, it must be eliminated, modified, and then added in the current answer.
The complexity analysis assumes that the block size is B. (Just look around, this part is not guaranteed to be correct ...) )
If both U and V do not move out of the block, then the position moves the complexity O (q*b), the time moving complexity O (q).
If v moves out of the block, the position moves complexity O (n*n/b) because Belong[u] is only n/b possible.
If you move out of the block, the location moves the complexity of O (n).
and Belong[u],belong[v] Only (n/b) ^2 species possible, so the complexity of time movement is O (q* (n/b) ^2).
Balance after b=n^ (2/3).
So the total complexity of O (n^ (5/3)).
Because the block size of the tree is actually larger than B, it is good to take b=n^ (2/3) *0.5 often.
#include <cmath>#include<cstdio>#include<cctype>#include<cstring>#include<algorithm>using namespacestd;intRead () {ints=0, t=1;CharC; while(!isdigit (C=getchar ()))if(c=='-') t=-1; Do{s=s*Ten+c-'0';} while(IsDigit (c=GetChar ())); returns*t;}Const intmaxn=100010;inttot,n,m,q,b,top,cnt,c0,c1;intfirst[maxn],deep[maxn],f[maxn][ -],BELONG[MAXN],ST[MAXN],NUM[MAXN],C[MAXN],W[MAXN],V[MAXN],PRE[MAXN];Long LongANS,ANS[MAXN];BOOLVIS[MAXN];structedge{intV from;} e[maxn*2];structe0=intX,y,pre;} A[MAXN];structc1{intX,y,t,id;} B[MAXN];voidInsertintUintV) {Tot++;e[tot].v=v;e[tot]. from=first[u];first[u]=tot;}voidDfsintXintFA) { intlim=top; for(intj=1;(1<<J) <=deep[x];j++) f[x][j]=f[f[x][j-1]][j-1]; for(intI=first[x];i;i=e[i]. from)if(e[i].v!=FA) {DEEP[E[I].V]=deep[x]+1; f[e[i].v][0]=x; DFS (E[I].V,X); if(top-lim>=B) {CNT++; while(Top>lim) belong[st[top--]]=CNT; }} st[++top]=x;}intLcaintXinty) { if(deep[x]<Deep[y]) swap (x, y); intd=deep[x]-Deep[y]; for(intj=0;(1<<J) <=d;j++)if((1<<J) &d) x=F[x][j]; if(x==y)returnx; for(intj= -; j>=0; j--)if((1<<J) <=deep[x]&&f[x][j]!=f[y][j]) x=f[x][j],y=F[y][j]; returnf[x][0];}voidReverseintx) { if(Vis[x]) ans-=1ll*w[num[c[x]]--]*V[c[x]]; Elseans+=1ll*w[++num[c[x]]]*V[c[x]]; VIS[X]^=1;}voidModifyintXinty) { if(!vis[x]) c[x]=y; ElseReverse (x), c[x]=y,reverse (x);}voidSolveintXinty) { while(x!=y) { if(Deep[x]>deep[y]) reverse (x), x=f[x][0]; ElseReverse (y), y=f[y][0]; }}BOOLCMP (C1 a,c1 b) {returnbelong[a.x]<belong[b.x]| | (Belong[a.x]==belong[b.x]&&belong[a.y]<belong[b.y]) | |(belong[a.x]==belong[b.x]&&belong[a.y]==belong[b.y]&&a.t<b.t);}intMain () {n=read (); M=read (); q=read (); for(intI=1; i<=m;i++) v[i]=read (); for(intI=1; i<=n;i++) w[i]=read (); for(intI=1; i<n;i++){ intU=read (), v=read (); Insert (u,v); insert (v,u); } B=pow (N,2.0/3)*0.5; DFS (1,0); while(top) belong[st[top--]]=CNT; for(intI=1; i<=n;i++) c[i]=pre[i]=read (); for(intI=1; i<=q;i++){ intKind=read (), X=read (), y=read (); if(!kind) {a[++c0]= (C0) {x,y,pre[x]},pre[x]=y; } Else{b[++c1]=(C1) {X,Y,C0,C1}; }} sort (b+1, b+c1+1, CMP); for(intI=1; i<=b[1].t;i++) modify (A[I].X,A[I].Y); Solve (b[1].x,b[1].y); intC=lca (b[1].x,b[1].y); Reverse (c); ans[b[1].id]=Ans;reverse (c); for(intI=2; i<=c1;i++){ for(intj=b[i-1].t+1; j<=b[i].t;j++) modify (A[J].X,A[J].Y); for(intj=b[i-1].t;j>b[i].t;j--) modify (A[j].x,a[j].pre); Solve (B[i-1].x,b[i].x); Solve (b[i-1].y,b[i].y); intC=LCA (B[I].X,B[I].Y); Reverse (c); Ans[b[i].id]=Ans;reverse (c); } for(intI=1; i<=c1;i++) printf ("%lld\n", Ans[i]); return 0;}
View Code
"Bzoj" 3052: [wc2013] Candy Park Tree sub-block + to be modified MO team algorithm