链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243
练了一发LCT,唔调了好久感觉是下传标记的问题可是不知道哪里错了。问了问老司机ljy,确实是出事了。。
唔大概就是 每一次flip的下传要注意一下两个儿子各自的lc和rc吧qwq
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }