Luogu 3690 LCT - 模板
推荐几篇比较好的博客:
FlashHu 的 讲解比较好 : 传送门
Candy 的 代码~ : 传送门
以及神犇Angel_Kitty的 学习笔记: 传送门
Code
V 模板
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define rd read() 5 #define ll long long 6 using namespace std; 7 8 const int N = 1e5 + 5; 9 const int mod = 51061; 10 11 int n, m; 12 13 int read() { 14 int X = 0, p = 1; char c = getchar(); 15 for (; c > '9' || c < '0'; c = getchar()) 16 if (c == '-') p = -1; 17 for (; c >= '0' && c <= '9'; c = getchar()) 18 X = X * 10 + c - '0'; 19 return X * p; 20 } 21 22 namespace LCT { 23 int ch[N][2], tun[N], f[N], size[N]; 24 ll sum[N], val[N], tim[N], ad[N]; 25 #define lc(x) ch[x][0] 26 #define rc(x) ch[x][1] 27 int isroot(int x) { 28 return lc(f[x]) != x && rc(f[x]) != x; 29 } 30 31 int get(int x) { 32 return rc(f[x]) == x; 33 } 34 35 void up(int x) { 36 sum[x] = val[x]; 37 size[x] = 1; 38 if (lc(x)) sum[x] += sum[lc(x)], size[x] += size[lc(x)]; 39 if (rc(x)) sum[x] += sum[rc(x)], size[x] += size[rc(x)]; 40 sum[x] %= mod; 41 } 42 43 void time(int x, ll d) { 44 val[x] = val[x] * d % mod; 45 sum[x] = sum[x] * d % mod; 46 ad[x] = ad[x] * d % mod; 47 tim[x] = tim[x] * d % mod; 48 } 49 50 void add(int x, ll d) { 51 sum[x] = (sum[x] + d * size[x]) % mod; 52 val[x] = (val[x] + d) % mod; 53 ad[x] = (ad[x] + d) % mod; 54 } 55 56 void rev(int x) { 57 swap(lc(x), rc(x)); 58 tun[x] ^= 1; 59 } 60 61 void pushdown(int x) { 62 if (tim[x] != 1) { 63 if (lc(x)) time(lc(x), tim[x]); 64 if (rc(x)) time(rc(x), tim[x]); 65 tim[x] = 1; 66 } 67 if (ad[x]) { 68 if (lc(x)) add(lc(x), ad[x]); 69 if (rc(x)) add(rc(x), ad[x]); 70 ad[x] = 0; 71 } 72 if (tun[x]) { 73 if (lc(x)) rev(lc(x)); 74 if (rc(x)) rev(rc(x)); 75 tun[x] = 0; 76 } 77 } 78 79 void pd(int x) { 80 if (!isroot(x)) 81 pd(f[x]); 82 pushdown(x); 83 } 84 85 void rotate(int x) { 86 int old = f[x], oldf = f[old], son = ch[x][get(x) ^ 1]; 87 if (!isroot(old)) ch[oldf][get(old)] = x; 88 ch[x][get(x) ^ 1] = old; 89 ch[old][get(x)] = son; 90 f[old] = x; f[x] = oldf; f[son] = old; 91 up(old); up(x); 92 } 93 94 void splay(int x) { 95 pd(x); 96 for (; !isroot(x); rotate(x)) 97 if(!isroot(f[x])) 98 rotate(get(f[x]) == get(x) ? f[x] : x); 99 } 100 101 void access(int x) { 102 for (int y = 0; x; y = x, x = f[x]) 103 splay(x), ch[x][1] = y, up(x); 104 } 105 106 void mroot(int x) { 107 access(x); splay(x); rev(x); 108 } 109 110 void split(int x, int y) { 111 mroot(x); access(y); splay(y); 112 } 113 114 void link(int x, int y) { 115 mroot(x); 116 f[x] = y; 117 } 118 119 void cut(int x, int y) { 120 split(x, y); 121 f[x] = ch[y][0] = 0; 122 up(y); 123 } 124 } 125 using namespace LCT; 126 127 int main() 128 { 129 n = rd; m = rd; 130 for (int i = 1; i <= n; ++i) 131 size[i] = tim[i] = val[i] = sum[i] = 1; 132 for (int i = 1; i < n; ++i) { 133 int u = rd, v = rd; 134 link(u, v); 135 } 136 for (; m; m--) { 137 char op[5]; 138 scanf("%s", op); 139 if (op[0] == '+') { 140 int u = rd, v = rd, d = rd; 141 split(u, v); 142 add(v, d); 143 } 144 if (op[0] == '-') { 145 int u = rd, v = rd; 146 cut(u, v); 147 u = rd; v = rd; 148 link(u, v); 149 } 150 if (op[0] == '*') { 151 int u = rd, v = rd, d = rd; 152 split(u, v); 153 time(v, d); 154 } 155 if (op[0] == '/') { 156 int u = rd, v = rd; 157 split(u, v); 158 printf("%lld\n", sum[v] % mod); 159 } 160 } 161 }