55// ! @code
66// ! ladder ld(adj);
77// ! // KACTL functions
8- // ! int kth_par = jmp(ld.b_tbl , v, k);
9- // ! int curr_lca = lca(ld.b_tbl , ld.d, u, v);
8+ // ! int kth_par = jmp(ld.jmp , v, k);
9+ // ! int curr_lca = lca(ld.jmp , ld.d, u, v);
1010// ! @endcode
1111struct ladder {
1212 int n;
13- vector<vi> b_tbl ;
14- vi d, p, dl, idx_l, l_tbl ;
13+ vi d, p, leaf, idx, lad ;
14+ vector<vi> jmp ;
1515 // ! @param adj forest (rooted or unrooted)
1616 // ! @time O(n log n)
17- // ! @space O(n log n) for b_tbl . Everything else is O(n)
17+ // ! @space O(n log n) for jmp . Everything else is O(n)
1818 ladder (const auto & adj):
19- n (sz(adj)), d(n), p(n, - 1 ), dl (n), idx_l( n) {
19+ n (sz(adj)), d(n), p(n), leaf(n ), idx (n), lad( 2 * n) {
2020 auto dfs = [&](auto && self, int v) -> void {
21- dl [v] = v;
21+ leaf [v] = v;
2222 for (int u : adj[v])
2323 if (u != p[v]) {
2424 d[u] = d[p[u] = v] + 1 ;
2525 self (self, u);
26- if (d[dl[u ]] > d[dl[v ]]) dl [v] = dl [u];
26+ if (d[leaf[v ]] < d[leaf[u ]]) leaf [v] = leaf [u];
2727 }
2828 };
29- rep (i, 0 , n) {
30- if (p[i] == -1 ) p[i] = i, dfs (dfs, i);
31- if (p[i] == i || dl[p[i]] != dl[i]) {
32- int v = dl[i], len = (d[v] - d[i]) * 2 ;
33- idx_l[v] = sz (l_tbl) + d[v];
34- for (; v != -1 && len--; v = p[v])
35- l_tbl.push_back (v);
36- }
29+ dfs (dfs, 0 );
30+ int pos = 0 ;
31+ rep (i, 0 , n) if (p[i] == i || leaf[p[i]] != leaf[i]) {
32+ int l = leaf[i];
33+ int len = min ((d[l] - d[i]) * 2 , d[l] + 1 );
34+ idx[l] = pos;
35+ for (; len--; l = p[l]) lad[pos++] = l;
3736 }
38- b_tbl = treeJump (p);
37+ jmp = treeJump (p);
3938 }
4039 // ! @param v query node
4140 // ! @param k number of edges
@@ -47,11 +46,11 @@ struct ladder {
4746 assert (0 <= k && k <= d[v]);
4847 if (k == 0 ) return v;
4948 int bit = __lg (k);
50- v = b_tbl [bit][v], k -= (1 << bit);
51- int l = idx_l[dl [v]] - d[v];
52- assert (l_tbl [l] == v);
53- // subarray [l, l+k] of l_tbl corresponds to the rest
49+ v = jmp [bit][v], k -= (1 << bit);
50+ int l = idx[leaf[v]] + d[leaf [v]] - d[v];
51+ assert (lad [l] == v);
52+ // subarray [l, l+k] of lad corresponds to the rest
5453 // of the jump
55- return l_tbl [l + k];
54+ return lad [l + k];
5655 }
5756};
0 commit comments