装饰

题目描述

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
", (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 }
原文地址:https://www.cnblogs.com/iamqzh233/p/9478563.html