"BZOJ2243" [SDOI2011] Dyeing description
Given a root tree and m operations with n nodes, there are 2 classes of operations:
1, the node a to node b path on all points are dyed color c;
2, query node a to node b path on the number of color segments (continuous same color is considered to be the same paragraph), such as "112221" consists of 3 paragraphs: "One", "222" and "1".
Please write a program to complete the m operation in turn.
Input
The first line contains 2 integers n and m, each representing the number of nodes and operands;
The second row contains n positive integers representing the initial color of n nodes
below each row of rows contains two integers x and y, indicating that there is an no-forward edge between x and y .
below each row of rows describes an action:
"c A b C" means that this is a dyeing operation, the node a to node b path on all points (including a and b) are dyed color C;
"Q a B" indicates that this is a query operation asking for the number of color segments on node a to node b(including a and b) paths.
Output
For each query operation, output one line of answers.
Sample INPUT6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5Sample OUTPUT3
1
2HINT
Number n<=10^5, operand m<=10^5, all color c is an integer and between [0, 10^9].
problem: Tree chain split + line tree template title, note that when the interval is merged to determine whether the adjacent endpoint color is the same.
#include <stdio.h>#include<string.h>#include<iostream>#defineLson x<<1#defineRson x<<1|1using namespacestd;Const intmaxn=100010;intN,m,cnt,tot;intFA[MAXN],DEEP[MAXN],SIZE[MAXN],SON[MAXN],TOP[MAXN];intto[maxn<<1],next[maxn<<1],HEAD[MAXN];intp[maxn],s[maxn<<2],sa[maxn<<2],sb[maxn<<2],u[maxn],v[maxn],tag[maxn<<2];Charstr[Ten];intReadin () {intret=0, sig=1;CharGC; while(gc<'0'|| Gc>'9') sig= (gc=='-')?-1:1, gc=GetChar (); while(gc>='0'&&gc<='9') ret=ret*Ten+gc-'0', gc=GetChar (); returnret*Sig;}voidAddintAintb) {to[cnt]=b; NEXT[CNT]=Head[a]; Head[a]=cnt++;}voidDFS1 (intx) {Size[x]=1; for(inti=head[x];i!=-1; i=Next[i]) { if(to[i]!=Fa[x]) {Deep[to[i]]=deep[x]+1; Fa[to[i]]=x; DFS1 (To[i]); SIZE[X]+=Size[to[i]]; if(Size[to[i]]>size[son[x]]) son[x]=To[i]; } }}voidDFS2 (intXintTP) {Top[x]=TP; P[X]=++tot; U[P[X]]=V[x]; if(Son[x]) DFS2 (SON[X],TP); for(inti=head[x];i!=-1; i=Next[i])if(to[i]!=fa[x]&&to[i]!=son[x]) DFS2 (To[i],to[i]);}voidPushup (intx) {S[x]=s[lson]+S[rson]; SA[X]=sa[lson],sb[x]=Sb[rson]; if(Sb[lson]==sa[rson]) s[x]--;}voidPushdown (intx) { if(Tag[x]) {Sa[lson]=sa[rson]=sb[lson]=sb[rson]=tag[lson]=tag[rson]=Tag[x]; S[lson]=s[rson]=1, tag[x]=0; }}voidBuildintLintRintx) { if(l==R) {S[x]=1, sa[x]=sb[x]=U[l]; return ; } intMid=l+r>>1; Build (L,mid,lson), Build (mid+1, R,rson); Pushup (x);}voidUpdata (intLintRintXintAintBintc) { if(a<=l&&r<=b) {s[x]=1, sa[x]=sb[x]=tag[x]=C; return ; } pushdown (x); intMid=l+r>>1; if(b<=mid) Updata (L,MID,LSON,A,B,C); Else if(A>mid) Updata (mid+1, R,rson,a,b,c); ElseUpdata (L,mid,lson,a,b,c), Updata (mid+1, R,rson,a,b,c); Pushup (x);}voidChangeintXinty) { intC=Readin (); while(top[x]!=Top[y]) { if(deep[top[x]]<Deep[top[y]]) swap (x, y); Updata (1N1, P[top[x]],p[x],c); X=Fa[top[x]]; } if(deep[x]>Deep[y]) swap (x, y); Updata (1N1, p[x],p[y],c);}intQueryintLintRintXintAintb) { if(a<=l&&r<=b)returnS[x]; Pushdown (x); intMid=l+r>>1; if(B<=mid)returnquery (L,MID,LSON,A,B); if(A>mid)returnQuery (mid+1, r,rson,a,b); returnQuery (l,mid,lson,a,b) +query (mid+1, R,rson,a,b)-(sb[lson]==Sa[rson]);}intGetColorintLintRintXinty) { if(L==R)returnSa[x]; Pushdown (x); intMid=l+r>>1; if(Y<=mid)returnGetColor (l,mid,lson,y); if(Y>mid)returnGetColor (mid+1, r,rson,y);}intGetans (intXinty) { intans=0; while(top[x]!=Top[y]) { if(deep[top[x]]<Deep[top[y]]) swap (x, y); Ans+=query (1N1, p[top[x]],p[x]); if(GetColor (1N1, P[top[x]]) ==getcolor (1N1, P[fa[top[x]]) ans--; //determine if the color of the endpoint is the samex=Fa[top[x]]; } if(deep[x]>Deep[y]) swap (x, y); Ans+=query (1N1, P[x],p[y]); printf ("%d\n", ans);}intMain () {n=readin (), m=Readin (); inti,a,b; memset (Head,-1,sizeof(head)); for(i=1; i<=n;i++) v[i]=Readin (); for(i=1; i<n;i++) {a=readin (), b=Readin (); Add (A, B), add (B,a); } deep[1]=1; DFS1 (1); DFS2 (1,1); Build (1N1); for(i=1; i<=m;i++) {scanf ("%s", str); A=readin (), b=Readin (); Switch(str[0]) { Case 'C': Change (A, b); Break; Case 'Q': Getans (A, b); Break; } } return 0;}
"BZOJ2243" [SDOI2011] staining tree chain split + segment tree