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. Ask node A to the number of color segments on Node B path (continuous same color is considered the same paragraph), such as "112221" consists of 3 segments: "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 5
Sample Output3
1
2
HINT
Number n<=10^5, operand m<=10^5, all color c is an integer and between [0, 10^9].
It's obviously a bare question ... I thought the dynamic tree was good to write some, however, a SB wrongly stared at 2h+. Can my Code ability still be used to feed the dog to describe it?
#include <cstdio>#include<cctype>#include<queue>#include<cmath>#include<cstring>#include<algorithm>#defineLC Ch[x][0]#defineRC Ch[x][1]#defineRep (i,s,t) for (int i=s;i<=t;i++)#defineDwn (i,s,t) for (int i=s;i>=t;i--)#defineren for (int i=first[x];i;i=next[i])using namespacestd;Const intBuffersize=1<< -;Charbuffer[buffersize],*head,*Tail;inlineCharGetchar () {if(head==tail) { intL=fread (Buffer,1, Buffersize,stdin); Tail= (Head=buffer) +l; } return*head++;} InlineintRead () {intx=0, f=1;CharC=GetChar (); for(;! IsDigit (c); C=getchar ())if(c=='-') f=-1; for(; IsDigit (c); C=getchar ()) x=x*Ten+c-'0'; returnx*F;}Const intmaxn=100010;intch[maxn][2],FA[MAXN],PRE[MAXN],SETV[MAXN],VAL[MAXN];intSUMV[MAXN],LEFT[MAXN],RIGHT[MAXN];intS[MAXN];voidMaintain (intx) {if(!x)return; if(Setv[x]) {left[x]=right[x]=setv[x];sumv[x]=1; return; } Sumv[x]=sumv[lc]+sumv[rc]+1; if(VAL[X]==LEFT[RC]) sumv[x]--; if(VAL[X]==RIGHT[LC]) sumv[x]--; LEFT[X]=LEFT[LC]?Left[lc]:val[x]; RIGHT[X]=RIGHT[RC]?right[rc]:val[x];}void Set(intXintv) {if(!x)return; SETV[X]=val[x]=left[x]=right[x]=v;sumv[x]=1;}voidPushdown (intx) {if(!x)return; if(Setv[x]) {Set(Lc,setv[x]);Set(Rc,setv[x]); SETV[X]=0; }}voidRotateintx) {inty=pre[x],z=pre[y],d=ch[y][0]==x; Ch[y][d^1]=CH[X][D];p re[ch[x][d]]=y; ch[z][ch[z][1]==y]=x;pre[x]=Z; CH[X][D]=y;pre[y]=X;maintain (y);}intS[maxn],top;voidSplay (intx) { for(intI=x;i;i=pre[i]) s[++top]=i; if(top!=1) fa[x]=fa[s[top]],fa[s[top]]=0; while(top) Pushdown (s[top--]); while(pre[x]) rotate (x); Maintain (x);}voidAccessintx) { for(inty=0; x;x=Fa[x]) {splay (x);p re[ch[x][1]]=0; fa[ch[x][1]]=x; ch[x][1]=y;pre[y]=x;maintain (y=x); }}voidSolveintXintYintTintv) {access (Y); for(y=0; x;x=Fa[x]) {splay (x); if(!Fa[x]) { if(t)Set(Y,V),Set(rc,v), val[x]=V,maintain (x); Else { intans=sumv[rc]+sumv[y]+1; if(VAL[X]==LEFT[RC]) ans--; if(Val[x]==left[y]) ans--; printf ("%d\n", ans); } return; } pre[ch[x][1]]=0; fa[ch[x][1]]=x; ch[x][1]=y;pre[y]=x;maintain (y=x); }}intfirst[maxn],next[maxn<<1],to[maxn<<1],e;voidAddedge (intUintv) {to[++e]=v;next[e]=first[u];first[u]=e; to[++e]=u;next[e]=first[v];first[v]=e;}intQ[MAXN],VIS[MAXN];voidBFsintx) {intL=1, r=0; q[++r]=x;vis[x]=1; while(l<=r) {x=q[l++]; renif(!Vis[to[i]]) {Fa[to[i]]=x; q[++r]=To[i]; Vis[to[i]]=1; } }}intMain () {intN=read (), m=read (); Rep (I,1, N)Set(I,read () +1); Rep (I,2, N) Addedge (read (), read ()); BFS (1); while(m--) { CharC=getchar (); while(!isalpha (c)) c=GetChar (); intU=read (), V=read (), x,t=0; if(c=='C') X=read () +1, t=1; Solve (u,v,t,x); } return 0;}
View Code
BZOJ2243: [SDOI2011] Dyeing