装饰
题目描述
Kokoa拼完了圣诞树,但是Chino觉得圣诞树光秃秃的一点不好看,所以决定装饰一下圣诞树。一开始所有点的权值pi为0, Chino每一次会选择树上两个点s,t,对于s-t,设上面的点为v1-k,给pvi加上iXRi。同时,Chino也会查询两个点a,b之间的简单路径上的所有点(包括a,b)的权值和(mod 100711433)。Chino还要接客,所以请你帮帮她。
输入
第一行3个整数 n,R,q
接下来n-1行 每行两个数a,b表示有一条边a,b
接下来q行 每行第一个数y表示操作种类
y=0 接下来3个整数 x,s,t 表示装饰操作
y=1 接下来2个整数 s,t 表示查询操作
输出
对于每个查询操作,单独一行输出一个数表示答案
样例输入
5 2 4
1 2
2 3
2 4
1 5
0 3 3 4
0 3 2 5
1 3 4
1 2 5
样例输出
108
126
提示
数据范围
30% n<=1e3 q<=2e3
另外20% R=1 X=1
另外30% 所有的装饰操作在查询操作之前
100% n<=1e5 q<=2e5 R,X<=1e9
这题考场我绝对码不动。。
首先树链剖分。
那么我们要用线段树来维护区间加$iXR^i$
那么我们发现$iXR^i$可以拆分成$(i-1)XR^i$和$XR,2XR^2…$
那么我们就可以用线段树来维护这两个标记了。
1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 #define M 200010 5 #define MOD 100711433 6 #define LL long long 7 inline int read() { 8 char ch = getchar(); int x = 0, f = 1; 9 while(ch < '0' || ch > '9') { 10 if(ch == '-') f = -1; 11 ch = getchar(); 12 } 13 while('0' <= ch && ch <= '9') { 14 x = x * 10 + ch - '0'; 15 ch = getchar(); 16 } 17 return x * f; 18 } 19 struct Edge{ 20 int u, v, Next; 21 } G[M * 2]; 22 int n, R, Q; 23 int head[M], tot; 24 int sz[M], id[M], Top[M], fa[M]; 25 int h[M], dfs_clock; 26 int q1[M], q2[M]; 27 int q[M * 4]; 28 int lz1[M * 4], lz2[M * 4], lz3[M * 4], lz4[M * 4]; 29 inline void add(int u, int v) { 30 G[++ tot] = (Edge){u, v, head[u]}; 31 head[u] = tot; 32 } 33 inline void dfs1(int x, int f) { 34 fa[x] = f; sz[x] = 1; 35 h[x] = h[f] + 1; 36 for(int i = head[x]; i != -1; i = G[i].Next) { 37 if(G[i].v == f) continue; 38 dfs1(G[i].v, x); 39 sz[x] += sz[G[i].v]; 40 } 41 } 42 inline void dfs2(int x, int f) { 43 int mx = 0; id[x] = ++ dfs_clock; 44 for(int i = head[x]; i != -1; i = G[i].Next) { 45 if(G[i].v == f) continue; 46 if(sz[G[i].v] > sz[mx]) mx = G[i].v; 47 } 48 if(mx) { 49 Top[mx] = Top[x]; 50 dfs2(mx, x); 51 } 52 for(int i = head[x]; i != -1; i = G[i].Next) { 53 if(G[i].v == f || G[i].v == mx) continue; 54 Top[G[i].v] = G[i].v; 55 dfs2(G[i].v, x); 56 } 57 } 58 inline int lca(int x, int y) { 59 while(Top[x] != Top[y]) { 60 if(h[Top[x]] < h[Top[y]]) swap(x, y); 61 x = fa[Top[x]]; 62 } 63 return (h[x] < h[y] ? x : y); 64 } 65 int mi[M]; 66 inline void init() { 67 mi[0] = 1; 68 for(int i = 1; i <= n; ++ i) { 69 mi[i] = 1ll * mi[i - 1] * R % MOD; 70 } 71 for(int i = 1; i <= n; ++ i) { 72 q1[i] = q1[i - 1] + mi[i - 1]; 73 if(q1[i] >= MOD) q1[i] -= MOD; 74 } 75 for(int i = 1; i <= n; ++ i) { 76 q2[i] = q2[i - 1] + 1ll * i * mi[i - 1] % MOD; 77 if(q2[i] >= MOD) q2[i] -= MOD; 78 } 79 } 80 inline void pd(int l, int mid, int r, int o) { 81 if(lz1[o]) { 82 q[2 * o] += 1ll * lz1[o] * q1[mid - l + 1] % MOD; 83 if(q[2 * o] >= MOD) q[2 * o] -= MOD; 84 q[2 * o + 1] += 1ll * lz1[o] * mi[mid - l + 1] % MOD * q1[r - mid] % MOD; 85 if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD; 86 lz1[2 * o] += lz1[o]; 87 if(lz1[2 * o] >= MOD) lz1[2 * o] -= MOD; 88 lz1[2 * o + 1] += 1ll * lz1[o] * mi[mid - l + 1] % MOD; 89 if(lz1[2 * o + 1] >= MOD) lz1[2 * o + 1] -= MOD; 90 lz1[o] = 0; 91 } 92 if(lz2[o]) { 93 q[2 * o] += 1ll * lz2[o] * q2[mid - l + 1] % MOD; 94 if(q[2 * o] >= MOD) q[2 * o] -= MOD; 95 q[2 * o + 1] += 1ll * lz2[o] * mi[mid - l + 1] % MOD * q2[r - mid] % MOD; 96 if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD; 97 q[2 * o + 1] += 1ll * lz2[o] * mi[mid - l + 1] % MOD * (mid - l + 1) % MOD * q1[r - mid] % MOD; 98 if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD; 99 lz2[2 * o] += lz2[o]; 100 if(lz2[2 * o] >= MOD) lz2[2 * o] -= MOD; 101 lz2[2 * o + 1] += 1ll * lz2[o] * mi[mid - l + 1] % MOD; 102 if(lz2[2 * o + 1] >= MOD) lz2[2 * o + 1] -= MOD; 103 lz1[2 * o + 1] += 1ll * lz2[o] * mi[mid - l + 1] % MOD * (mid - l + 1) % MOD; 104 if(lz1[2 * o + 1] >= MOD) lz1[2 * o + 1] -= MOD; 105 lz2[o] = 0; 106 } 107 if(lz3[o]) { 108 q[2 * o] += 1ll * lz3[o] * mi[r - mid] % MOD * q1[mid - l + 1] % MOD; 109 if(q[2 * o] >= MOD) q[2 * o] -= MOD; 110 q[2 * o + 1] += 1ll * lz3[o] * q1[r - mid] % MOD; 111 if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD; 112 lz3[2 * o] += 1ll * lz3[o] * mi[r - mid] % MOD; 113 if(lz3[2 * o] >= MOD) lz3[2 * o] -= MOD; 114 lz3[2 * o + 1] += lz3[o]; 115 if(lz3[2 * o + 1] >= MOD) lz3[2 * o + 1] -= MOD; 116 lz3[o] = 0; 117 } 118 if(lz4[o]) { 119 q[2 * o] += 1ll * lz4[o] * mi[r - mid] % MOD * q2[mid - l + 1] % MOD; 120 if(q[2 * o] >= MOD) q[2 * o] -= MOD; 121 q[2 * o] += 1ll * lz4[o] * mi[r - mid] % MOD * (r - mid) % MOD * q1[mid - l + 1] % MOD; 122 if(q[2 * o] >= MOD) q[2 * o] -= MOD; 123 q[2 * o + 1] += 1ll * lz4[o] * q2[r - mid] % MOD; 124 if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD; 125 lz4[2 * o] += 1ll * lz4[o] * mi[r - mid] % MOD; 126 if(lz4[2 * o] >= MOD) lz4[2 * o] -= MOD; 127 lz3[2 * o] += 1ll * lz4[o] * mi[r - mid] % MOD * (r - mid) % MOD; 128 if(lz3[2 * o] >= MOD) lz3[2 * o] -= MOD; 129 lz4[2 * o + 1] += lz4[o]; 130 if(lz4[2 * o + 1] >= MOD) lz4[2 * o + 1] -= MOD; 131 lz4[o] = 0; 132 } 133 } 134 inline void Do1(int l, int r, int o, int x, int y, int k, int st) { 135 if(x <= l && r <= y) { 136 k = 1ll * k * mi[st] % MOD; -- st; 137 q[o] += 1ll * q2[r - l + 1] * k % MOD; 138 if(q[o] >= MOD) q[o] -= MOD; 139 lz2[o] += k; 140 if(lz2[o] >= MOD) lz2[o] -= MOD; 141 if(st) { 142 q[o] += 1ll * q1[r - l + 1] * k % MOD * st % MOD; 143 if(q[o] >= MOD) q[o] -= MOD; 144 lz1[o] += 1ll * k * st % MOD; 145 if(lz1[o] >= MOD) lz1[o] -= MOD; 146 } 147 return; 148 } 149 int mid = (l + r) / 2; 150 pd(l, mid, r, o); 151 if(y <= mid) { 152 Do1(l, mid, 2 * o, x, y, k, st); 153 } 154 else if(x > mid) { 155 Do1(mid + 1, r, 2 * o + 1, x, y, k, st); 156 } 157 else { 158 Do1(l, mid, 2 * o, x, mid, k, st); 159 Do1(mid + 1, r, 2 * o + 1, mid + 1, y, k, st + mid - x + 1); 160 } 161 q[o] = q[2 * o] + q[2 * o + 1]; 162 if(q[o] >= MOD) q[o] -= MOD; 163 } 164 inline void Do2(int l, int r, int o, int x, int y, int k, int st) { 165 if(x <= l && r <= y) { 166 k = 1ll * k * mi[st] % MOD; -- st; 167 q[o] += 1ll * q2[r - l + 1] * k % MOD; 168 if(q[o] >= MOD) q[o] -= MOD; 169 lz4[o] += k; 170 if(lz4[o] >= MOD) lz4[o] -= MOD; 171 if(st) { 172 q[o] += 1ll * q1[r - l + 1] * k % MOD * st % MOD; 173 if(q[o] >= MOD) q[o] -= MOD; 174 lz3[o] += 1ll * k * st % MOD; 175 if(lz3[o] >= MOD) lz3[o] -= MOD; 176 } 177 return; 178 } 179 int mid = (l + r) / 2; 180 pd(l, mid, r, o); 181 if(y <= mid) { 182 Do2(l, mid, 2 * o, x, y, k, st); 183 } 184 else if(x > mid) { 185 Do2(mid + 1, r, 2 * o + 1, x, y, k, st); 186 } 187 else { 188 Do2(l, mid, 2 * o, x, mid, k, st + y - mid); 189 Do2(mid + 1, r, 2 * o + 1, mid + 1, y, k, st); 190 } 191 q[o] = q[2 * o] + q[2 * o + 1]; 192 if(q[o] >= MOD) q[o] -= MOD; 193 } 194 inline int query(int l, int r, int o, int x, int y) { 195 if(x <= l && r <= y) { 196 if(q[o] < 0) { 197 while(1); 198 } 199 return q[o]; 200 } 201 int mid = (l + r) / 2, ret = 0; 202 pd(l, mid, r, o); 203 if(x <= mid) ret += query(l, mid, 2 * o, x, y); 204 if(y > mid) ret += query(mid + 1, r, 2 * o + 1, x, y); 205 if(ret >= MOD) ret -= MOD; 206 return ret; 207 } 208 signed main() { 209 n = read(), R = read(), Q = read(); 210 memset(head, -1, sizeof(head)); 211 for(int i = 1; i < n; ++ i) { 212 int u = read(), v = read(); 213 add(u, v); add(v, u); 214 } 215 dfs1(1, 0); 216 Top[1] = 1; 217 dfs2(1, 0); 218 init(); 219 while(Q --) { 220 int op = read(); 221 if(op == 1) { 222 int x = read(), y = read(); 223 int Ans = 0; 224 while(Top[x] != Top[y]) { 225 if(h[Top[x]] < h[Top[y]]) swap(x, y); 226 Ans += query(1, n, 1, id[Top[x]], id[x]); 227 if(Ans >= MOD) Ans -= MOD; 228 x = fa[Top[x]]; 229 } 230 if(h[x] > h[y]) swap(x, y); 231 Ans += query(1, n, 1, id[x], id[y]); 232 if(Ans >= MOD) Ans -= MOD; 233 printf("%d\n", (Ans + MOD) % MOD); 234 } 235 else { 236 int X = read(), x = read(), y = read(); 237 X %= MOD; 238 int LCA = lca(x, y), now = h[x] + h[y] - 2 * h[LCA] + 1; 239 while(Top[y] != Top[LCA]) { 240 Do1(1, n, 1, id[Top[y]], id[y], X, now - (id[y] - id[Top[y]])); 241 now -= (id[y] - id[Top[y]] + 1); 242 y = fa[Top[y]]; 243 } 244 if(h[LCA] < h[y]) { 245 Do1(1, n, 1, id[LCA] + 1, id[y], X, now - (id[y] - id[LCA] - 1)); 246 } 247 now = 1; 248 while(Top[x] != Top[LCA]) { 249 Do2(1, n, 1, id[Top[x]], id[x], X, now); 250 now += (id[x] - id[Top[x]]) + 1; 251 x = fa[Top[x]]; 252 } 253 if(h[LCA] <= h[x]) { 254 Do2(1, n, 1, id[LCA], id[x], X, now); 255 } 256 } 257 } 258 }