/tmp/solutions/build/jump_on_tree-slow.cpp:
1| |#include <common.h>
2| |prelude;
3| |
4| |namespace {
5| |
6| |constexpr int N = 5e5;
7| |
8| |struct {
9| | int to;
10| | int nxt;
11| |} edge[N * 2];
12| |int head[N];
13| |int size[N];
14| |int depth[N];
15| |int heavy[N];
16| |int ances[N];
17| |int parent[N];
18| |int node2id[N];
19| |int id2node[N];
20| |int id;
21| |
22| 500k|def build_step_1(int u, int d, int p) -> void {
23| 500k| size[u] = 1;
24| 500k| depth[u] = d;
25| 500k| parent[u] = p;
26| 1.49M| for (int e = head[u]; e; e = edge[e].nxt) {
^999k
------------------
| Branch (26:25): [True: 66.67%, False: 33.33%]
------------------
27| 999k| if (int v = edge[e].to; v != p) {
------------------
| Branch (27:29): [True: 50.00%, False: 50.00%]
------------------
28| 499k| build_step_1(v, d + 1, u);
29| 499k| size[u] += size[v];
30| 499k| if (heavy[u] == 0 || size[v] > size[heavy[u]]) {
^187k
------------------
| Branch (30:11): [True: 62.44%, False: 37.56%]
| Branch (30:28): [True: 40.24%, False: 59.76%]
------------------
31| 387k| heavy[u] = v;
32| 387k| }
33| 499k| }
34| 999k| }
35| 500k|}
36| |
37| 500k|def build_step_2(int u, int a, int p) -> void {
38| 500k| node2id[u] = id;
39| 500k| id2node[id] = u;
40| 500k| ++id;
41| 500k| ances[u] = a;
42| 500k| if (heavy[u]) build_step_2(heavy[u], a, u);
^312k
------------------
| Branch (42:7): [True: 62.44%, False: 37.56%]
------------------
43| 1.49M| for (int e = head[u]; e; e = edge[e].nxt) {
^999k
------------------
| Branch (43:25): [True: 66.67%, False: 33.33%]
------------------
44| 999k| if (int v = edge[e].to; v != heavy[u] && v != p) {
^687k
------------------
| Branch (44:29): [True: 68.78%, False: 31.22%]
| Branch (44:46): [True: 27.30%, False: 72.70%]
------------------
45| 187k| build_step_2(v, v, u);
46| 187k| }
47| 999k| }
48| 500k|}
49| |
50| 500k|def lca(int u, int v) -> int {
51| 1.28M| while (ances[u] != ances[v]) {
------------------
| Branch (51:10): [True: 60.95%, False: 39.05%]
------------------
52| 780k| if (depth[ances[u]] > depth[ances[v]]) {
------------------
| Branch (52:9): [True: 49.95%, False: 50.05%]
------------------
53| 389k| u = parent[ances[u]];
54| 390k| } else {
55| 390k| v = parent[ances[v]];
56| 390k| }
57| 780k| }
58| 500k| return depth[u] < depth[v] ? u : v;
^249k^250k
------------------
| Branch (58:10): [True: 49.83%, False: 50.17%]
------------------
59| 500k|}
60| |
61| 458k|def jump(int u, int d) -> int {
62| 701k| while (depth[ances[u]] > d) {
------------------
| Branch (62:10): [True: 34.66%, False: 65.34%]
------------------
63| 243k| u = parent[ances[u]];
64| 243k| }
65| 458k| return id2node[node2id[u] - depth[u] + d];
66| 458k|}
67| |
68| |} // namespace
69| |
70| 1|int main() {
71| 1| rd rd;
72| 1| wt wt;
73| 1| int n = rd.uh();
74| 1| int q = rd.uh();
75| 1|#ifdef LOCAL
76| 1| id = 0;
77| 1| std::memset(head, 0, 4 * n);
78| 1| std::memset(heavy, 0, 4 * n);
79| 1| std::memset(parent, 0, 4 * n);
80| 1|#endif
81| 500k| for (int i = 1; i < n; ++i) {
^499k
------------------
| Branch (81:19): [True: 100.00%, False: 0.00%]
------------------
82| 499k| int a = rd.uh();
83| 499k| int b = rd.uh();
84| 499k| edge[i * 2 | 0] = {b, head[a]}, head[a] = i * 2 | 0;
85| 499k| edge[i * 2 | 1] = {a, head[b]}, head[b] = i * 2 | 1;
86| 499k| }
87| 1| build_step_1(0, 0, -1);
88| 1| build_step_2(0, 0, -1);
89| 500k| while (q--) {
------------------
| Branch (89:10): [True: 100.00%, False: 0.00%]
------------------
90| 500k| int u = rd.uh();
91| 500k| int v = rd.uh();
92| 500k| int k = rd.uh();
93| 500k| int w = lca(u, v);
94| 500k| int du = depth[u];
95| 500k| int dv = depth[v];
96| 500k| int dw = depth[w];
97| 500k| if (k <= du - dw) {
------------------
| Branch (97:9): [True: 45.82%, False: 54.18%]
------------------
98| 229k| int x = jump(u, du - k);
99| 229k| wt.uw(x);
100| 270k| } else if (k <= du + dv - dw - dw) {
------------------
| Branch (100:16): [True: 84.61%, False: 15.39%]
------------------
101| 229k| int x = jump(v, dw + dw - du + k);
102| 229k| wt.uw(x);
103| 229k| } else {
104| 41.6k| wt.puts(" -1", 3);
105| 41.6k| }
106| 500k| }
107| 1| return 0;
108| 1|}