/tmp/solutions/build/dynamic_tree_subtree_add_subtree_sum-main.cpp:
1| |#include <common.h>
2| |prelude;
3| |
4| |namespace {
5| |
6| |constexpr int N = 200001;
7| |
8| |struct Node {
9| | i64 sum;
10| | i64 sum_;
11| | i64 add;
12| | int size;
13| | int size_;
14| | int p;
15| | int ch[2];
16| | i8 rev;
17| | i8 k;
18| |} node[N];
19| |
20| 2.15M|def reverse(int x) -> void { node[x].rev ^= 1; }
21| |
22| 3.87M|def pushdown(int x) -> void {
23| 3.87M| if (node[x].rev) {
------------------
| Branch (23:7): [True: 26.08%, False: 73.92%]
------------------
24| 1.01M| std::swap(node[x].ch[0], node[x].ch[1]);
25| 1.01M| node[node[x].ch[0]].k = 0;
26| 1.01M| node[node[x].ch[1]].k = 1;
27| 1.01M| reverse(node[x].ch[0]);
28| 1.01M| reverse(node[x].ch[1]);
29| 1.01M| node[x].rev = 0;
30| 1.01M| }
31| 3.87M|}
32| |
33| 3.57M|def maintain(int x) -> void {
34| 3.57M| node[x].size =
35| 3.57M| node[node[x].ch[0]].size + 1 + node[node[x].ch[1]].size + node[x].size_;
36| 3.57M| node[x].sum = node[node[x].ch[0]].sum + node[node[x].ch[1]].sum +
37| 3.57M| node[x].sum_ + node[x].size * node[x].add;
38| 3.57M|}
39| |
40| 2.54M|def rotateup(int x) -> void {
41| 2.54M| int p = node[x].p;
42| 2.54M| int g = node[p].p;
43| 2.54M| int k = node[x].k;
44| 2.54M| int t = node[p].k;
45| 2.54M| i64 b = node[x].add;
46| 2.54M| i64 a = node[p].add;
47| 2.54M| node[x].add = a + b;
48| 2.54M| node[p].add = -b;
49| 2.54M| node[node[x].ch[k ^ 1]].add += b;
50| 2.54M| node[node[x].ch[k ^ 1]].sum += b * node[node[x].ch[k ^ 1]].size;
51| 2.54M| node[node[x].ch[k ^ 1]].p = p;
52| 2.54M| node[node[x].ch[k ^ 1]].k = k;
53| 2.54M| node[p].ch[k] = node[x].ch[k ^ 1];
54| 2.54M| node[p].p = x;
55| 2.54M| node[p].k = k ^ 1;
56| 2.54M| node[x].ch[k ^ 1] = p;
57| 2.54M| node[x].p = g;
58| 2.54M| node[x].k = t;
59| 2.54M| if (t != -1) {
------------------
| Branch (59:7): [True: 41.90%, False: 58.10%]
------------------
60| 1.06M| node[g].ch[t] = x;
61| 1.06M| }
62| 2.54M| maintain(p);
63| 2.54M|}
64| |
65| 3.17M|def is_root(int x) -> bool { return node[x].k == -1; }
66| |
67| 1.03M|def splay(int x) -> void {
68| 1.03M| pushdown(x);
69| 2.10M| while (!is_root(x)) {
------------------
| Branch (69:10): [True: 51.01%, False: 48.99%]
------------------
70| 1.07M| if (int p = node[x].p; is_root(p)) {
------------------
| Branch (70:28): [True: 34.55%, False: 65.45%]
------------------
71| 370k| pushdown(p);
72| 370k| pushdown(x);
73| 370k| rotateup(x);
74| 702k| } else {
75| 702k| int g = node[p].p;
76| 702k| pushdown(g);
77| 702k| pushdown(p);
78| 702k| pushdown(x);
79| 702k| if (node[x].k == node[p].k) {
------------------
| Branch (79:11): [True: 54.18%, False: 45.82%]
------------------
80| 380k| rotateup(p);
81| 380k| rotateup(x);
82| 380k| } else {
83| 321k| rotateup(x);
84| 321k| rotateup(x);
85| 321k| }
86| 702k| }
87| 1.07M| }
88| 1.03M|}
89| |
90| 264k|def access(int x) -> void {
91| 264k| splay(x);
92| 264k| node[node[x].ch[1]].k = -1;
93| 264k| node[x].sum_ += node[node[x].ch[1]].sum;
94| 264k| node[x].size_ += node[node[x].ch[1]].size;
95| 264k| node[x].ch[1] = 0;
96| 264k| maintain(x);
97| 1.03M| while (int p = node[x].p) {
------------------
| Branch (97:14): [True: 74.35%, False: 25.65%]
------------------
98| 765k| splay(p);
99| 765k| node[node[p].ch[1]].k = -1;
100| 765k| node[p].sum_ += node[node[p].ch[1]].sum;
101| 765k| node[p].size_ += node[node[p].ch[1]].size;
102| 765k| node[p].sum_ -= node[x].sum;
103| 765k| node[p].size_ -= node[x].size;
104| 765k| node[p].ch[1] = x;
105| 765k| node[x].k = 1;
106| 765k| rotateup(x);
107| 765k| maintain(x);
108| 765k| }
109| 264k|}
110| |
111| |int head[N];
112| |struct {
113| | int to;
114| | int next;
115| |} edge[N * 2];
116| |
117| 14.8k|def build(int u, int p) -> void {
118| 44.6k| for (int e = head[u]; e; e = edge[e].next) {
^29.7k
------------------
| Branch (118:25): [True: 66.67%, False: 33.33%]
------------------
119| 29.7k| int v = edge[e].to;
120| 29.7k| if (v != p) {
------------------
| Branch (120:9): [True: 50.00%, False: 50.00%]
------------------
121| 14.8k| build(v, u);
122| 14.8k| node[v + 1].p = u + 1;
123| 14.8k| node[u + 1].sum_ += node[v + 1].sum;
124| 14.8k| node[u + 1].size_ += node[v + 1].size;
125| 14.8k| }
126| 29.7k| }
127| 14.8k| node[u + 1].sum = node[u + 1].sum_;
128| 14.8k| node[u + 1].size = node[u + 1].size_ + 1;
129| 14.8k|}
130| |
131| |} // namespace
132| |
133| 1|int main() {
134| 1| rd rd;
135| 1| wt wt;
136| 1| int n = rd.uh();
137| 1| int q = rd.uh();
138| 1|#ifdef LOCAL
139| 1| std::memset(head, 0, 4 * n);
140| 1|#endif
141| 14.8k| for (int i = 1; i <= n; ++i) node[i] = {.sum_ = rd.uw(), .k = -1};
^14.8k^14.8k
------------------
| Branch (141:19): [True: 99.99%, False: 0.01%]
------------------
142| 14.8k| for (int i = 1; i != n; ++i) {
^14.8k
------------------
| Branch (142:19): [True: 99.99%, False: 0.01%]
------------------
143| 14.8k| int u = rd.uh();
144| 14.8k| int v = rd.uh();
145| 14.8k| edge[i * 2 | 0] = {v, head[u]}, head[u] = i * 2 | 0;
146| 14.8k| edge[i * 2 | 1] = {u, head[v]}, head[v] = i * 2 | 1;
147| 14.8k| }
148| 1| build(0, 0);
149| 99.1k| while (q--) {
------------------
| Branch (149:10): [True: 100.00%, False: 0.00%]
------------------
150| 99.1k| let t = rd.u1();
151| 99.1k| if (t == 0) {
------------------
| Branch (151:9): [True: 33.28%, False: 66.72%]
------------------
152| 32.9k| int u = rd.uh() + 1;
153| 32.9k| int v = rd.uh() + 1;
154| 32.9k| access(u);
155| 32.9k| reverse(u);
156| 32.9k| access(v);
157| 32.9k| node[node[v].ch[0]].p = 0;
158| 32.9k| node[node[v].ch[0]].k = -1;
159| 32.9k| node[node[v].ch[0]].add += node[v].add;
160| 32.9k| node[v].ch[0] = 0;
161| 32.9k| int w = rd.uh() + 1;
162| 32.9k| int x = rd.uh() + 1;
163| 32.9k| access(w);
164| 32.9k| reverse(w);
165| 32.9k| access(x);
166| 32.9k| node[w].p = x;
167| 32.9k| node[w].add -= node[x].add;
168| 32.9k| node[w].sum -= node[x].add * node[w].size;
169| 32.9k| node[x].sum_ += node[w].sum;
170| 32.9k| node[x].size_ += node[w].size;
171| 32.9k| }
172| 99.1k| if (t == 1) {
------------------
| Branch (172:9): [True: 33.26%, False: 66.74%]
------------------
173| 32.9k| int u = rd.uh() + 1;
174| 32.9k| int p = rd.uh() + 1;
175| 32.9k| i64 x = rd.uw();
176| 32.9k| access(u);
177| 32.9k| reverse(u);
178| 32.9k| access(p);
179| 32.9k| node[u].add += x;
180| 32.9k| node[u].sum += x * node[u].size;
181| 32.9k| }
182| 99.1k| if (t == 2) {
------------------
| Branch (182:9): [True: 33.46%, False: 66.54%]
------------------
183| 33.1k| int u = rd.uh() + 1;
184| 33.1k| int p = rd.uh() + 1;
185| 33.1k| access(u);
186| 33.1k| reverse(u);
187| 33.1k| access(p);
188| 33.1k| i64 ans = node[u].sum + node[u].size * node[p].add;
189| 33.1k| wt.ud(ans);
190| 33.1k| }
191| 99.1k| }
192| 1| return 0;
193| 1|}