Test Instructions:Link
Method:Mo Team on the tree
parsing:First of all, consider a team of algorithms, tree block and then how to do it? You can set two pointers, and then move the pointer in a certain sort of way so that the complexity can be over. Observed that the problem is 100s, n^2 is GG, but slightly smaller than n^2 is not GG, so the role of sequencing is reflected. According to the block of the left endpoint is the first keyword, the right end of the block is the second keyword occurrence time for the Third keyword sort. There is a total of N of 1/3 square blocks, so all the queries of the left and right end of the block is the most value of the next N of 2/3 of the species, for each, the modification of the time will change from the tail to the head, so multiply by a q,n,q the same order, so the total complexity O (N^5/3), If the two endpoints of the two queries are within the same block, the complexity is transferred within the block, and the size of each block is N^2/3 times, so the complexity is also O (N^5/3). Not forced to O (n^2). And then change it? Bind the violence and change it. Count the number of queries before each change. Each time the enumeration is asked, the violence modifies the modification operation. Of course to sort, so it seems more linear 2333 and then the team on the tree ~ Don't read the wrong question!
Code:
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 100100Using namespace Std;typedef long long ll;intNm,Q, CNT;intHead[n];ll V[n],w[n];intC[n];intSta[n];intBelong[n];intDeep[n];intfa[n][ +];int s[N];intV[n];llPrint[N];intStatus[n];intsqr23n;intTot,top,cntque,cntcha;struct node{intFrom,to,Next;} edge[n<<1];struct query{intL,r,blockl,blockr,appcha,lca,No, Alltime;} Que[n];struct change{intPt,pre, Sub, No,alltime;}cha[n];void init () {memset (head,-1, sizeof (head)); Cnt=1;} void Edgeadd (intFromintTo) {edge[cnt].to=to; EDGE[CNT].Next=head[from]; head[from]=cnt++;} void Dfs (intNowintDepthintFAFA) {v[now]=1, fa[now][0]=fafa,deep[now]=depth;intBot=top; for(inti=head[now];i!=-1; I=edge[i].Next) {intto=edge[i].to;if(V[to])Continue; DFS (to,depth+1, now);if(top-bot>=sqr23n) {tot++; Do{Belong[sta[top--]]=tot; } while(Top!=bot); }} Sta[++top]=now;}intLcaint x,int y){if(deep[x]<deep[y]) Swap (x,y); for(intI= -; i>=0; i--) {if(deep[fa[x][i]]>=deep[y]&&fa[x][i]!=0)x=fa[x][i]; } for(intI= -; i>=0; i--) {if(fa[x][i]!=fa[y][i]&&fa[x][i]!=0&&fa[y][i]!=0)x=fa[x][i],y=fa[y][i]; }if(x==y)return x;returnfa[x][0];} ll Ans;void UPD (int x){if(status[x]) {status[x]=0; ans-=w[s[c[x]]]*v[c[x]];s[c[x]]--; }Else{status[x]=1;s[c[x]]++; ans+=w[s[c[x]]]*v[c[x]]; }}void Update (intUintVintLCA) { while(U!=LCA) {UPD (U); u=fa[u][0]; } while(V!=LCA) {UPD (v); v=fa[v][0]; }}intCMP (query A,query b) {if(A.blockl==b.blockl) {if(A.blockr==b.blockr) {returna.appcha<b.appcha; }Else returna.blockr<b.blockr; }Else returnA.blockl<b.blockl;} void Trans (intChaidintOPT) {intflag=0;if(opt) flag=1, swap (cha[chaid].pre,cha[chaid].sub); C[cha[chaid].pt]=cha[chaid].sub;if(status[cha[chaid].pt]) {Ans-=v[cha[chaid].pre]*w[s[Cha[chaid].pre]];s[cha[chaid].pre]--;s[cha[chaid].sub]++; Ans+=v[cha[chaid].sub]*w[s[Cha[chaid].sub]]; }if(flag) Swap (cha[chaid].pre,cha[chaid].sub); }intMain () {init (); scanf" %d%d%d",&n,&m,&Q); Sqr23n=pow (N,2.0/3.0); for(intI=1; i<=m; i++) scanf ("%lld", &v[i]); for(intI=1; i<=n;i++) scanf ("%lld", &w[i]); for(intI=1; i<n;i++) {int x,y; scanf"%d%d",&x,&y); Edgeadd (x,y), Edgeadd (y,x); } DFS (1,1,0); while(top>0) {Belong[sta[top--]]=tot; } for(intI=1; i<= -; i++) { for(intj=1; j<=n;j++) {fa[j][i]=fa[fa[j][i-1]][i-1]; } } for(intI=1; i<=n;i++) scanf ("%d", &c[i]); for(intI=1; i<=Q; i++) {intJdx,y; scanf" %d%d%d",&jd,&x,&y);if(JD) {if(belong[x]>belong[y]) Swap (x,y); Que[++cntque].l=x, que[cntque].r=y; que[cntque].blockl=belong[x],que[cntque].blockr=belong[y]; Que[cntque].appcha=cntcha; Que[cntque].lca=lca (QUE[CNTQUE].L,QUE[CNTQUE].R); Que[cntque].No=cntque; Que[cntque].alltime=cntque; }Else{cha[++cntcha].pt=x, cha[cntcha].pre=c[x],cha[cntcha].sub=c[x]=y, Cha[cntcha].No=cntcha; Cha[cntcha].alltime=cntque; } }Sort(que+1, que+cntque+1, CMP);intCnntcha=cntcha; Update (que[1].l,que[1].r,que[1].LCA); UPD (que[1].LCA); while(cnntcha>0) {if(cha[cnntcha].alltime<que[1].alltime) Break; Trans (Cnntcha,1); cnntcha--; } while(Cnntcha<cntcha) {if(cha[cnntcha+1].alltime>=que[1].alltime) Break; Trans (cnntcha+1,0); cnntcha++; }Print[que[1].No]=ans; UPD (que[1].LCA);inttl=que[1].L,TR=que[1].R; for(intI=2; i<=cntque;i++) {intTmp=lca (QUE[I].L,TL); Update (TL,QUE[I].L,TMP); Tmp=lca (QUE[I].R,TR); UpdateTR, que[i].r,tmp); UPD (QUE[I].LCA); while(cnntcha>0) {if(Cha[cnntcha].alltime<que[i].alltime) Break; Trans (Cnntcha,1); cnntcha--; } while(Cnntcha<cntcha) {if(cha[cnntcha+1].alltime>=que[i].alltime) Break; Trans (cnntcha+1,0); cnntcha++; }Print[Que[i].No]=ans; UPD (QUE[I].LCA); TL=QUE[I].L,TR=QUE[I].R; } for(intI=1; i<=cntque;i++)printf("%lld\ n",Print[i]);}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Bzoj 3052 [wc2013] Candy Park tree on the MO team