Fork me on GitHub

【BZOJ 2243】染色

传送门洛谷   BZOJ

还不会LCT的小伙伴可以看一下这篇博客:LCT总结

我初学动态树时就是看着那篇博客学的,写的很好!

那好 言归正传。

显然树上 x 到 y 的路径的问题都可以用LCT Access一下把路径剖离出来,那主要问题在于如何用Splay 来维护颜色呢?

上图(XP 灵魂画手

 

 

对于Splay树的每一个节点,维护四个信息

c[x] : 节点本身的颜色

cL[x]: 节点对应子树最左端的颜色

cR[x]: 节点对应子树最右端的颜色

tot[x]: 节点对应子树区间的颜色段数

所以upDATA的时候就很显然啦~

 1 void pUP(int x){
 2     int lc=ch[x][0],rc=ch[x][1];
 3 
 4     cL[x]= lc? cL[lc]:c[x];
 5     cR[x]= rc? cR[rc]:c[x];
 6 
 7     if(lc && rc) tot[x]=tot[lc]+tot[rc]+1-(cR[lc]==c[x])-(cL[rc]==c[x]);
 8 
 9     if(lc &&!rc) tot[x]=tot[lc]+1-(cR[lc]==c[x]);
10 
11     if(!lc&& rc) tot[x]=tot[rc]+1-(cL[rc]==c[x]);
12 
13     if(!lc&&!rc) tot[x]=1;
14 }

其他部分就和平常的LCT没有什么区别了

哦 对,pushDOWN时要注意 区间翻转,cL和cR要一起翻

全代码~

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<algorithm>
  6 
  7 #define For(i,a,b) for(register int i=a;i<=b;++i)
  8 #define Dwn(i,a,b) for(register int i=a;i>=b;--i)
  9 #define Pn putchar('\n')
 10 #define I inline 
 11 #define Re register
 12 
 13 using namespace std;
 14 
 15 const int N=1e5+5;
 16 
 17 int ch[N][2],fa[N],c[N],cL[N],cR[N],tot[N],tag[N],st[N],top,tgC[N];
 18 int n,m,x,y,z;
 19 char opt;
 20 
 21 I void read(int &v){
 22     v=0;
 23     char c=getchar();
 24     while(c<'0'||c>'9')c=getchar();
 25     while(c>='0'&&c<='9')v=v*10+c-'0',c=getchar();
 26 }
 27 void write(int x){
 28     if(x>9)write(x/10);
 29     int xx=x%10;
 30     putchar(xx+'0');
 31 }
 32 I bool NOrt(int x){
 33     return ch[fa[x]][1]==x || ch[fa[x]][0]==x;
 34 }
 35 I void pTAG(int x){
 36     swap(ch[x][0],ch[x][1]);
 37     swap(cL[x],cR[x]);
 38     tag[x]^=1;
 39 }
 40 I void pTGC(int x,int Col){
 41     c[x]=cL[x]=cR[x]=Col;
 42     tot[x]=1;
 43     tgC[x]=Col;
 44 }
 45 I void pDOWN(int x){
 46     if(tag[x]){
 47         if(ch[x][0])pTAG(ch[x][0]);
 48         if(ch[x][1])pTAG(ch[x][1]);
 49         tag[x]^=1;
 50     }
 51     if(tgC[x]){
 52         if(ch[x][0])pTGC(ch[x][0],tgC[x]);
 53         if(ch[x][1])pTGC(ch[x][1],tgC[x]);
 54         tgC[x]=0;
 55     }
 56 }
 57 I void pUP(int x){
 58     int lc=ch[x][0],rc=ch[x][1];
 59     
 60     cL[x]= lc? cL[lc]:c[x];
 61     cR[x]= rc? cR[rc]:c[x];
 62     
 63     if(lc && rc) tot[x]=tot[lc]+tot[rc]+1-(cR[lc]==c[x])-(cL[rc]==c[x]);
 64     
 65     if(lc &&!rc) tot[x]=tot[lc]+1-(cR[lc]==c[x]);
 66     
 67     if(!lc&& rc) tot[x]=tot[rc]+1-(cL[rc]==c[x]);
 68     
 69     if(!lc&&!rc) tot[x]=1;
 70 }
 71 I bool Wson(int x){
 72     return ch[fa[x]][1]==x;
 73 }
 74 I void Rotate(int x){
 75     int y=fa[x];
 76     int z=fa[y];
 77     int ws=Wson(x);
 78     if(NOrt(y))ch[z][Wson(y)]=x;
 79     fa[x]=z;
 80     
 81     ch[y][ws]=ch[x][ws^1];
 82     if(ch[x][ws^1])fa[ch[x][ws^1]]=y;
 83     
 84     ch[x][ws^1]=y;
 85     fa[y]=x;
 86     
 87     pUP(y); pUP(x);
 88 }
 89 I void Splay(int x){
 90     top=0; int now=x;
 91     st[++top]=now;
 92     while(NOrt(now))st[++top]=now=fa[now];
 93     while(top) pDOWN(st[top--]);
 94     
 95     while(NOrt(x)){
 96         int y=fa[x];
 97         if(NOrt(y)){
 98             if(Wson(y)==Wson(x))Rotate(y);
 99             else Rotate(x);
100         }
101         Rotate(x);
102     }
103 }
104 I void Access(int x){
105     int lst=0;
106     while(x){
107         Splay(x); ch[x][1]=lst; pUP(x);
108         lst=x; x=fa[x];
109     }
110 }
111 I void ChangeRt(int x){
112     Access(x); Splay(x); pTAG(x);
113 }
114 I void Link(int x,int y){
115     ChangeRt(x); fa[x]=y;
116 }
117 I void Split(int x,int y){
118     ChangeRt(x); Access(y); Splay(y);
119 }
120 int main(){ 
121     read(n); read(m); 
122     For(i,1,n){
123         read(c[i]); tot[i]=1;
124         cL[i]=cR[i]=c[i]; 
125     };
126     For(i,1,n-1){ 
127         read(x); read(y);
128         Link(x,y);
129     }
130     For(i,1,m){ 
131         opt=getchar();
132         while(opt!='C'&&opt!='Q')opt=getchar();
133         if(opt=='C'){
134             read(x); read(y); read(z);
135             Split(x,y); pTGC(y,z);
136         }
137         if(opt=='Q'){
138             read(x); read(y);
139             Split(x,y);
140             write(tot[y]); Pn;
141         }
142     }
143     return 0;
144 }

 

posted @ 2019-01-28 17:00  H_LAUV  阅读(293)  评论(0编辑  收藏  举报
Live2D //博客园自带,可加可不加