【BZOJ2243】【SDOI2011】染色 (LCT)

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243

练了一发LCT,唔调了好久感觉是下传标记的问题可是不知道哪里错了。问了问老司机ljy,确实是出事了。。

唔大概就是 每一次flip的下传要注意一下两个儿子各自的lc和rc吧qwq

 

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <iostream>
  5 #define MaxN 200010
  6 using namespace std;
  7 int n, m, top;
  8 int ch[MaxN][2];
  9 int Q[MaxN], sum[MaxN], val[MaxN], type[MaxN], flip[MaxN], p[MaxN], mark[MaxN], lc[MaxN], rc[MaxN];
 10 //splay
 11 
 12 bool isroot(int x){
 13     return ch[p[x]][0] != x && ch[p[x]][1] != x;
 14 }
 15 
 16 #define l ch[x][0]
 17 #define r ch[x][1]
 18 
 19 void push_up(int x){
 20     sum[x] = sum[l] + sum[r] + 1;
 21     if (l) sum[x] -= (rc[l] == val[x]), lc[x] = lc[l]; else lc[x] = val[x];
 22     if (r) sum[x] -= (lc[r] == val[x]), rc[x] = rc[r]; else rc[x] = val[x];
 23 }
 24 
 25 void updata(int x, int c){
 26     if (!x) return;
 27     sum[x] = mark[x] = 1; 
 28     lc[x] = rc[x] = val[x] = c;
 29 }
 30 
 31 void Flip(int x){
 32     flip[x] ^= 1; swap(lc[l], rc[l]); swap(rc[r], lc[r]);
 33 }
 34 
 35 #undef l
 36 #undef r
 37 
 38 void push_down(int x){
 39     int l = ch[x][0], r = ch[x][1];
 40     if (flip[x]){
 41         flip[x] = 0;
 42         Flip(l); Flip(r);        
 43         swap(ch[x][0], ch[x][1]);
 44     }
 45     if (mark[x]){
 46         mark[x] = 0;
 47         updata(l, val[x]); updata(r, val[x]); 
 48     }
 49 }
 50 
 51 void rotate(int x){
 52     int y = p[x], z = p[y];
 53     if (!isroot(y)) ch[z][ch[z][1] == y] = x;
 54     int l = ch[y][1] == x, r = l ^ 1;
 55     
 56     p[x] = z;
 57     p[y] = x;
 58     p[ch[x][r]] = y;
 59     
 60     ch[y][l] = ch[x][r];
 61     ch[x][r] = y;
 62     push_up(y); push_up(x);
 63 }
 64 
 65 void splay(int x){
 66     int top = 1;
 67     Q[top] = x;
 68     for (int t = x; !isroot(t); t = p[t]) Q[++top] = p[t];
 69     while (top) push_down(Q[top--]);
 70     while (!isroot(x)){
 71         int y = p[x], z = p[y];
 72         if (!isroot(y)){
 73             if ((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(x);
 74             else rotate(y);
 75         }
 76         rotate(x);
 77     }
 78 }
 79 
 80 // lct
 81 
 82 void Access(int x){
 83     for (int t = 0; x; t = x, x = p[x]) {
 84         splay(x); ch[x][1] = t; push_up(x);
 85     }
 86 }
 87 
 88 void Make_root(int x){
 89     Access(x); splay(x); flip[x] ^= 1;
 90 }
 91 
 92 void Link(int u, int v){
 93     Make_root(u); p[u] = v;
 94 }
 95 
 96 void Split(int u, int v){
 97     Make_root(v); Access(u); splay(u);
 98 }
 99 
100 //
101 void Read_Data(){
102     scanf("%d%d", &n, &m);
103     int u, v;
104     //val[0] = rc[0] = lc[0] = -1;
105     for (int i = 1; i <= n; i++) scanf("%d", &val[i]), lc[i] = rc[i] = val[i];
106 //    for (int i = 1; i <= n; i++) sum[i] = 1; 
107     for (int i = 1; i < n; i++) {    
108         scanf("%d%d", &u, &v);
109         Link(u, v); 
110         
111 }
112 
113 void Solve(){
114     char s[5];
115     int u, v, c;
116     for (int i = 1; i <= m; i++) {
117         scanf("%s%d%d", s, &u, &v);
118         if (s[0] == 'Q') {
119             Split(u, v); 
120             printf("%d\n", sum[u]);
121         }
122         else {
123             scanf("%d", &c);
124             Split(u, v); updata(u, c); 
125         }    
126     }
127 }
128 
129 int main(){
130     freopen("paint.in", "r", stdin);
131     freopen("paint.out", "w", stdout);
132     Read_Data();
133     Solve();
134     return 0;
135 }
_(:з」∠)_

 

转载于:https://www.cnblogs.com/Lukaluka/p/5147114.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值