diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 3779b25b..020171b8 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -141,7 +141,7 @@ "tests/library_checker_aizu_tests/trees/hld_lib_checker_path.test.cpp": "2026-04-12 16:21:27 -0600", "tests/library_checker_aizu_tests/trees/hld_lib_checker_subtree_edges.test.cpp": "2026-04-12 16:21:27 -0600", "tests/library_checker_aizu_tests/trees/hld_lib_checker_subtree_nodes.test.cpp": "2026-04-12 16:21:27 -0600", -"tests/library_checker_aizu_tests/trees/kth_path_ladder.test.cpp": "2026-04-15 11:43:31 -0600", +"tests/library_checker_aizu_tests/trees/kth_path_ladder.test.cpp": "2026-04-25 21:16:20 -0600", "tests/library_checker_aizu_tests/trees/kth_path_linear.test.cpp": "2026-04-21 13:56:58 -0600", "tests/library_checker_aizu_tests/trees/kth_path_tree_lift.test.cpp": "2026-04-12 16:21:27 -0600", "tests/library_checker_aizu_tests/trees/lca_all_methods_aizu.test.cpp": "2026-04-21 13:56:58 -0600", diff --git a/library/trees/uncommon/ladder_decomposition.hpp b/library/trees/uncommon/ladder_decomposition.hpp index 7dede21c..ff3e8fcc 100644 --- a/library/trees/uncommon/ladder_decomposition.hpp +++ b/library/trees/uncommon/ladder_decomposition.hpp @@ -2,55 +2,56 @@ #include "../../../kactl/content/graph/BinaryLifting.h" //! https://codeforces.com/blog/entry/71567#comment-559299 //! https://youtu.be/0rCFkuQS968 +//! https://codeforces.com/blog/entry/153250 //! @code //! ladder ld(g); +//! ld.kth_par(u, k); // kth parent of u +//! ld.kth_par(u, 0); // u +//! ld.kth_par(u, 1); // p[u] //! // KACTL functions //! int kth_par = jmp(ld.jmp, u, k); //! int curr_lca = lca(ld.jmp, ld.d, u, v); //! @endcode struct ladder { int n; - vi d, p, leaf, idx, lad; + vi d, p, idx, l; vector jmp; //! @param g forest (rooted or unrooted) //! @time O(n log n) //! @space O(n log n) for jmp. Everything else is O(n) ladder(const auto& g): - n(sz(g)), d(n), p(n), leaf(n), idx(n), lad(2 * n) { - auto dfs = [&](auto dfs, int u) -> void { - leaf[u] = u; + n(sz(g)), d(n), p(n), idx(n), l(2 * n) { + int i = 0; + vi s(n); + auto dfs = [&](auto dfs, int u) -> vi { + vi path; + s[d[u]] = u; for (int v : g[u]) if (v != p[u]) { d[v] = d[p[v] = u] + 1; - dfs(dfs, v); - if (d[leaf[u]] < d[leaf[v]]) leaf[u] = leaf[v]; + vi x = dfs(dfs, v); + if (sz(x) > sz(path)) swap(x, path); + for (int y : x) idx[y] = i; + for (int y : x) l[i++] = y; + rep(j, 0, min(sz(x), d[v])) l[i++] = s[d[u] - j]; } + path.push_back(u); + return path; }; - dfs(dfs, 0); - int pos = 0; - rep(i, 0, n) if (p[i] == i || leaf[p[i]] != leaf[i]) { - int l = leaf[i]; - int len = min((d[l] - d[i]) * 2, d[l] + 1); - idx[l] = pos; - for (; len--; l = p[l]) lad[pos++] = l; - } + vi x = dfs(dfs, 0); + for (int y : x) idx[y] = i; + for (int y : x) l[i++] = y; jmp = treeJump(p); } - //! @param u query node - //! @param k number of edges - //! @returns a node k edges up from u. With k=1, this - //! returns u's parent. - //! @time O(1) - //! @space O(1) int kth_par(int u, int k) { assert(0 <= k && k <= d[u]); if (k == 0) return u; int bit = __lg(k); u = jmp[bit][u], k -= (1 << bit); - int l = idx[leaf[u]] + d[leaf[u]] - d[u]; - assert(lad[l] == u); - // subarray [l, l+k] of lad corresponds to the rest + int i = idx[u], j = i + d[l[i]] - d[u]; + assert(l[j] == u); + // subarray [j, j+k] of l corresponds to the rest // of the jump - return lad[l + k]; + return l[j + k]; } }; diff --git a/tests/library_checker_aizu_tests/trees/kth_path_ladder.test.cpp b/tests/library_checker_aizu_tests/trees/kth_path_ladder.test.cpp index 93d84f55..0aa10aa3 100644 --- a/tests/library_checker_aizu_tests/trees/kth_path_ladder.test.cpp +++ b/tests/library_checker_aizu_tests/trees/kth_path_ladder.test.cpp @@ -1,8 +1,9 @@ #define PROBLEM \ "https://judge.yosupo.jp/problem/jump_on_tree" #include "../template.hpp" +#undef sz +#define sz(x) (int)ssize(x) #include "../../../library/trees/uncommon/ladder_decomposition.hpp" -#include "../../../library/trees/uncommon/linear_kth_par.hpp" int main() { cin.tie(0)->sync_with_stdio(0); int n, q;