/tmp/solutions/build/dynamic_tree_vertex_add_path_sum-main.cpp:
1| |#include <common.h>
2| |prelude;
3| |
4| |namespace {
5| |
6| |constexpr int N = 200001;
7| |
8| |struct Node {
9| | u64 val;
10| | u64 sum;
11| | int p;
12| | int ch[2];
13| | i8 rev;
14| | i8 k;
15| |} node[N];
16| |
17| 33.1M|def reverse(int x) -> void { node[x].rev ^= 1; }
18| |
19| 53.1M|def pushdown(int x) -> void {
20| 53.1M| if (node[x].rev) {
------------------
| Branch (20:7): [True: 29.71%, False: 70.29%]
------------------
21| 15.7M| std::swap(node[x].ch[0], node[x].ch[1]);
22| 15.7M| node[node[x].ch[0]].k = 0;
23| 15.7M| node[node[x].ch[1]].k = 1;
24| 15.7M| reverse(node[x].ch[0]);
25| 15.7M| reverse(node[x].ch[1]);
26| 15.7M| node[x].rev = 0;
27| 15.7M| }
28| 53.1M|}
29| |
30| 34.7M|def maintain(int x) -> void {
31| 34.7M| node[x].sum = node[node[x].ch[0]].sum + node[x].val + node[node[x].ch[1]].sum;
32| 34.7M|}
33| |
34| 34.7M|def rotateup(int x) -> void {
35| 34.7M| int p = node[x].p;
36| 34.7M| int g = node[p].p;
37| 34.7M| int k = node[x].k;
38| 34.7M| int t = node[p].k;
39| 34.7M| node[node[x].ch[k ^ 1]].p = p;
40| 34.7M| node[node[x].ch[k ^ 1]].k = k;
41| 34.7M| node[p].ch[k] = node[x].ch[k ^ 1];
42| 34.7M| node[p].p = x;
43| 34.7M| node[p].k = k ^ 1;
44| 34.7M| node[x].ch[k ^ 1] = p;
45| 34.7M| node[x].p = g;
46| 34.7M| node[x].k = t;
47| 34.7M| if (t != -1) {
------------------
| Branch (47:7): [True: 51.47%, False: 48.53%]
------------------
48| 17.9M| node[g].ch[t] = x;
49| 17.9M| }
50| 34.7M| maintain(p);
51| 34.7M|}
52| |
53| 42.4M|def is_root(int x) -> bool { return node[x].k == -1; }
54| |
55| 11.9M|def splay(int x) -> void {
56| 11.9M| pushdown(x);
57| 27.2M| while (!is_root(x)) {
------------------
| Branch (57:10): [True: 56.15%, False: 43.85%]
------------------
58| 15.2M| if (int p = node[x].p; is_root(p)) {
------------------
| Branch (58:28): [True: 30.24%, False: 69.76%]
------------------
59| 4.62M| pushdown(p);
60| 4.62M| pushdown(x);
61| 4.62M| rotateup(x);
62| 10.6M| } else {
63| 10.6M| int g = node[p].p;
64| 10.6M| pushdown(g);
65| 10.6M| pushdown(p);
66| 10.6M| pushdown(x);
67| 10.6M| if (node[x].k == node[p].k) {
------------------
| Branch (67:11): [True: 51.32%, False: 48.68%]
------------------
68| 5.47M| rotateup(p);
69| 5.47M| rotateup(x);
70| 5.47M| } else {
71| 5.18M| rotateup(x);
72| 5.18M| rotateup(x);
73| 5.18M| }
74| 10.6M| }
75| 15.2M| }
76| 11.9M|}
77| |
78| 2.57M|def access(int x) -> void {
79| 2.57M| splay(x);
80| 2.57M| node[node[x].ch[1]].k = -1;
81| 2.57M| node[x].ch[1] = 0;
82| 11.4M| while (int p = node[x].p) {
------------------
| Branch (82:14): [True: 77.49%, False: 22.51%]
------------------
83| 8.84M| splay(p);
84| 8.84M| node[node[p].ch[1]].k = -1;
85| 8.84M| node[p].ch[1] = x;
86| 8.84M| node[x].k = 1;
87| 8.84M| rotateup(x);
88| 8.84M| }
89| 2.57M|}
90| |
91| |int head[N];
92| |struct {
93| | int to;
94| | int next;
95| |} edge[N * 2];
96| |
97| 1.51M|def build(int u, int p) -> void {
98| 4.54M| for (int e = head[u]; e; e = edge[e].next) {
^3.02M
------------------
| Branch (98:25): [True: 66.67%, False: 33.33%]
------------------
99| 3.02M| int v = edge[e].to;
100| 3.02M| if (v != p) {
------------------
| Branch (100:9): [True: 50.00%, False: 50.00%]
------------------
101| 1.51M| build(v, u);
102| 1.51M| node[v + 1].p = u + 1;
103| 1.51M| }
104| 3.02M| }
105| 1.51M|}
106| |
107| |} // namespace
108| |
109| 14|int main() {
110| 14| rd rd;
111| 14| wt wt;
112| 14| int n = rd.uh();
113| 14| int q = rd.uh();
114| 14|#ifdef LOCAL
115| 14| std::memset(head, 0, 4 * n);
116| 14|#endif
117| 1.51M| for (int i = 1; i <= n; ++i)
^1.51M
------------------
| Branch (117:19): [True: 100.00%, False: 0.00%]
------------------
118| 1.51M| node[i] = {.k = -1}, node[i].sum = node[i].val = rd.uw();
119| 1.51M| for (int i = 1; i != n; ++i) {
^1.51M
------------------
| Branch (119:19): [True: 100.00%, False: 0.00%]
------------------
120| 1.51M| int u = rd.uh();
121| 1.51M| int v = rd.uh();
122| 1.51M| edge[i * 2 | 0] = {v, head[u]}, head[u] = i * 2 | 0;
123| 1.51M| edge[i * 2 | 1] = {u, head[v]}, head[v] = i * 2 | 1;
124| 1.51M| }
125| 14| build(0, 0);
126| 1.54M| while (q--) {
------------------
| Branch (126:10): [True: 100.00%, False: 0.00%]
------------------
127| 1.54M| let t = rd.u1();
128| 1.54M| if (t == 0) {
------------------
| Branch (128:9): [True: 33.31%, False: 66.69%]
------------------
129| 514k| int u = rd.uh() + 1;
130| 514k| int v = rd.uh() + 1;
131| 514k| access(u);
132| 514k| reverse(u);
133| 514k| access(v);
134| 514k| node[node[v].ch[0]].p = 0;
135| 514k| node[node[v].ch[0]].k = -1;
136| 514k| node[v].ch[0] = 0;
137| 514k| int w = rd.uh() + 1;
138| 514k| int x = rd.uh() + 1;
139| 514k| access(w);
140| 514k| reverse(w);
141| 514k| node[w].p = x;
142| 514k| }
143| 1.54M| if (t == 1) {
------------------
| Branch (143:9): [True: 33.38%, False: 66.62%]
------------------
144| 515k| int u = rd.uh() + 1;
145| 515k| u32 x = rd.uw();
146| 515k| splay(u);
147| 515k| node[u].val += x;
148| 515k| node[u].sum += x;
149| 515k| }
150| 1.54M| if (t == 2) {
------------------
| Branch (150:9): [True: 33.32%, False: 66.68%]
------------------
151| 514k| int u = rd.uh() + 1;
152| 514k| int v = rd.uh() + 1;
153| 514k| access(u);
154| 514k| reverse(u);
155| 514k| access(v);
156| 514k| wt.ud(node[node[v].ch[0]].sum + node[v].val);
157| 514k| }
158| 1.54M| }
159| 14| return 0;
160| 14|}