Skip to content

Commit c1b4665

Browse files
committed
update ladder decomp
1 parent 804ce52 commit c1b4665

2 files changed

Lines changed: 25 additions & 25 deletions

File tree

library/trees/uncommon/ladder_decomposition.hpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,53 @@
44
//! https://youtu.be/0rCFkuQS968
55
//! @code
66
//! ladder ld(g);
7+
//! ld.kth_par(u, k); // kth parent of u
8+
//! ld.kth_par(u, 0); // u
9+
//! ld.kth_par(u, 1); // p[u]
710
//! // KACTL functions
811
//! int kth_par = jmp(ld.jmp, u, k);
912
//! int curr_lca = lca(ld.jmp, ld.d, u, v);
1013
//! @endcode
1114
struct ladder {
1215
int n;
13-
vi d, p, leaf, idx, lad;
16+
vi d, p, idx, l;
1417
vector<vi> jmp;
1518
//! @param g forest (rooted or unrooted)
1619
//! @time O(n log n)
1720
//! @space O(n log n) for jmp. Everything else is O(n)
1821
ladder(const auto& g):
19-
n(sz(g)), d(n), p(n), leaf(n), idx(n), lad(2 * n) {
20-
auto dfs = [&](auto dfs, int u) -> void {
21-
leaf[u] = u;
22+
n(sz(g)), d(n), p(n), idx(n), l(2 * n) {
23+
int i = 0;
24+
vi s(n);
25+
auto dfs = [&](auto dfs, int u) -> vi {
26+
vi path;
27+
s[d[u]] = u;
2228
for (int v : g[u])
2329
if (v != p[u]) {
2430
d[v] = d[p[v] = u] + 1;
25-
dfs(dfs, v);
26-
if (d[leaf[u]] < d[leaf[v]]) leaf[u] = leaf[v];
31+
vi x = dfs(dfs, v);
32+
if (sz(x) > sz(path)) swap(x, path);
33+
for (int y : x) idx[y] = i;
34+
for (int y : x) l[i++] = y;
35+
rep(j, 0, min(sz(x), d[v])) l[i++] = s[d[u] - j];
2736
}
37+
path.push_back(u);
38+
return path;
2839
};
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;
36-
}
40+
vi x = dfs(dfs, 0);
41+
for (int y : x) idx[y] = i;
42+
for (int y : x) l[i++] = y;
3743
jmp = treeJump(p);
3844
}
39-
//! @param u query node
40-
//! @param k number of edges
41-
//! @returns a node k edges up from u. With k=1, this
42-
//! returns u's parent.
43-
//! @time O(1)
44-
//! @space O(1)
4545
int kth_par(int u, int k) {
4646
assert(0 <= k && k <= d[u]);
4747
if (k == 0) return u;
4848
int bit = __lg(k);
4949
u = jmp[bit][u], k -= (1 << bit);
50-
int l = idx[leaf[u]] + d[leaf[u]] - d[u];
51-
assert(lad[l] == u);
52-
// subarray [l, l+k] of lad corresponds to the rest
50+
int i = idx[u], j = i + d[l[i]] - d[u];
51+
assert(l[j] == u);
52+
// subarray [j, j+k] of l corresponds to the rest
5353
// of the jump
54-
return lad[l + k];
54+
return l[j + k];
5555
}
5656
};

tests/library_checker_aizu_tests/trees/kth_path_ladder.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#define PROBLEM \
22
"https://judge.yosupo.jp/problem/jump_on_tree"
33
#include "../template.hpp"
4+
#define sz(x) (int)ssize(x)
45
#include "../../../library/trees/uncommon/ladder_decomposition.hpp"
5-
#include "../../../library/trees/uncommon/linear_kth_par.hpp"
66
int main() {
77
cin.tie(0)->sync_with_stdio(0);
88
int n, q;

0 commit comments

Comments
 (0)