【BZOJ2631】tree (LCT)
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2631
终于学了LCT惹qwq (看的板是黄学长的orzzz
T了很久发现窝开了个ch[MaxN][0] ,这都能编译过?
1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #include <algorithm> 5 #define mod 51061 6 #define MaxN 100010 7 using namespace std; 8 int n, q; 9 int ch[MaxN][2]; 10 unsigned int sum[MaxN], sz[MaxN], ad[MaxN], mu[MaxN], Q[MaxN], p[MaxN], flip[MaxN], val[MaxN]; 11 12 void updata(int x, int m, int a){ 13 val[x] = (val[x]*m + a) % mod; 14 sum[x] = (sum[x]*m + a*sz[x]) % mod; 15 ad[x] = (ad[x] * m + a) % mod; 16 mu[x] = (mu[x] * m) % mod; 17 } 18 19 void push_up(int x){ 20 int l = ch[x][0], r = ch[x][1]; 21 sz[x] = (sz[l]+sz[r]+1) % mod; 22 sum[x] = (sum[l]+sum[r]+val[x]) % mod; 23 } 24 25 void push_down(int x){ 26 int l = ch[x][0], r = ch[x][1]; 27 if (flip[x]) { 28 flip[x] = 0; flip[l] ^= 1; flip[r] ^= 1; 29 swap(ch[x][0], ch[x][1]); 30 } 31 int m = mu[x], a = ad[x]; 32 if (m != 1 || a != 0) { 33 updata(l, m, a); 34 updata(r, m, a); 35 mu[x] = 1, ad[x] = 0; 36 } 37 } 38 39 bool isroot(int x){ 40 return ch[p[x]][0] != x && ch[p[x]][1] != x; 41 } 42 43 void rotate(int x){ 44 int y = p[x], z = p[y]; 45 if (!isroot(y)) ch[z][ch[z][1] == y] = x; 46 int l = ch[y][1] == x, r = l ^ 1; 47 p[y] = x; 48 p[x] = z; 49 p[ch[x][r]] = y; 50 51 ch[y][l] = ch[x][r]; 52 ch[x][r] = y; 53 push_up(y); 54 push_up(x); 55 } 56 57 void splay(int x){ 58 int top = 1; 59 Q[top] = x; 60 for (int t = x; !isroot(t); t = p[t]) Q[++top] = p[t]; 61 while (top) push_down(Q[top--]); 62 while (!isroot(x)){ 63 int y = p[x], z = p[y]; 64 if (!isroot(y)){ 65 if ((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(x); 66 else rotate(y); 67 } 68 rotate(x); 69 } 70 } 71 72 void Access(int x){ 73 for (int t = 0; x; t = x, x = p[x]){ 74 splay(x); ch[x][1] = t; push_up(x); 75 } 76 } 77 78 void Make_root(int x){ 79 Access(x); splay(x); flip[x] ^= 1; 80 } 81 82 void Link(int u, int v){ 83 Make_root(u); p[u] = v; 84 } 85 86 void Cut(int u, int v){ 87 Make_root(u); Access(v); splay(v); 88 p[u] = ch[v][0] = 0; 89 } 90 91 void Split(int u, int v){ 92 Make_root(v); Access(u); splay(u); 93 } 94 95 void Read_Data(){ 96 scanf("%d%d", &n, &q); 97 for (int i = 1; i <= n; i++) 98 sum[i] = sz[i] = mu[i] = val[i] = 1; 99 for (int i = 1, u, v; i < n; i++){ 100 scanf("%d%d", &u, &v); 101 Link(u, v); 102 } 103 } 104 105 void Solve(){ 106 char s[5]; 107 int u, v, c, u2, v2; 108 for (int i = 1; i <= q; i++){ 109 scanf("%s%d%d", s, &u, &v); 110 if (s[0] == '+') { 111 scanf("%d", &c); 112 Split(u, v); updata(u, 1, c); 113 } 114 if (s[0] == '-') { 115 scanf("%d%d", &u2, &v2); 116 Cut(u, v); Link(u2, v2); 117 } 118 if (s[0] == '*') { 119 scanf("%d", &c); 120 Split(u, v); updata(u, c, 0); 121 } 122 if (s[0] == '/') { 123 Split(u, v); 124 printf("%d\n", sum[u]); 125 } 126 } 127 } 128 129 int main(){ 130 freopen("bzoj2631.in", "r", stdin); 131 freopen("bzoj2631.out", "w", stdout); 132 Read_Data(); 133 Solve(); 134 return 0; 135 }