diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 66180855..f094c5f5 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -70,7 +70,7 @@ "tests/library_checker_aizu_tests/handmade_tests/dsu_size.test.cpp": "2024-09-22 18:42:16 -0500", "tests/library_checker_aizu_tests/handmade_tests/edge_cd_small_trees.test.cpp": "2024-09-21 13:04:45 -0500", "tests/library_checker_aizu_tests/handmade_tests/fib_matrix_expo.test.cpp": "2024-09-23 11:20:46 -0500", -"tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2024-10-17 00:12:45 -0700", +"tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2024-10-17 18:15:46 -0700", "tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-10-06 21:59:37 -0700", "tests/library_checker_aizu_tests/handmade_tests/merge_sort_trees.test.cpp": "2024-09-22 18:42:16 -0500", "tests/library_checker_aizu_tests/handmade_tests/mobius.test.cpp": "2024-09-19 12:57:45 -0700", @@ -138,8 +138,8 @@ "tests/library_checker_aizu_tests/trees/edge_cd_contour_range_update.test.cpp": "2024-09-22 18:42:16 -0500", "tests/library_checker_aizu_tests/trees/edge_cd_count_paths_per_length.test.cpp": "2024-09-21 13:04:45 -0500", "tests/library_checker_aizu_tests/trees/edge_cd_reroot_dp.test.cpp": "2024-09-21 13:04:45 -0500", -"tests/library_checker_aizu_tests/trees/kth_node_on_path.test.cpp": "2024-10-17 00:12:45 -0700", -"tests/library_checker_aizu_tests/trees/ladder_decomposition.test.cpp": "2024-10-17 00:12:45 -0700", +"tests/library_checker_aizu_tests/trees/kth_node_on_path.test.cpp": "2024-10-17 18:15:46 -0700", +"tests/library_checker_aizu_tests/trees/ladder_decomposition.test.cpp": "2024-10-17 18:15:46 -0700", "tests/library_checker_aizu_tests/trees/lca_all_methods_aizu.test.cpp": "2024-10-07 00:04:04 -0700", "tests/library_checker_aizu_tests/trees/lca_all_methods_lib_checker.test.cpp": "2024-10-07 00:04:04 -0700", "tests/library_checker_aizu_tests/trees/subtree_isomorphism.test.cpp": "2024-09-19 12:57:45 -0700" diff --git a/library/trees/ladder_decomposition/ladder_decomposition.hpp b/library/trees/ladder_decomposition/ladder_decomposition.hpp index 45da02c1..d081a27e 100644 --- a/library/trees/ladder_decomposition/ladder_decomposition.hpp +++ b/library/trees/ladder_decomposition/ladder_decomposition.hpp @@ -10,13 +10,13 @@ //! @endcode struct ladder { int n; - vector b_tbl, l_tbl; - vi d, p, dl; //!< deepest leaf + vector b_tbl; + vi d, p, dl, idx_l, l_tbl; //! @param adj forest (rooted or unrooted) //! @time O(n log n) //! @space O(n log n) for b_tbl. Everything else is O(n) ladder(const vector& adj): - n(sz(adj)), l_tbl(n), d(n), p(n, -1), dl(n) { + n(sz(adj)), d(n), p(n, -1), dl(n), idx_l(n) { auto dfs = [&](auto&& self, int v) -> void { dl[v] = v; for (int u : adj[v]) @@ -29,11 +29,10 @@ struct ladder { rep(i, 0, n) { if (p[i] == -1) p[i] = i, dfs(dfs, i); if (p[i] == i || dl[p[i]] != dl[i]) { - int leaf = dl[i]; - vi& lad = l_tbl[leaf]; - lad.resize(min(2 * (d[leaf] - d[i]), d[leaf] + 1), - leaf); - rep(j, 1, sz(lad)) lad[j] = p[lad[j - 1]]; + int v = dl[i], len = (d[v] - d[i]) * 2; + idx_l[v] = sz(l_tbl) + d[v]; + for (; v != -1 && len--; v = p[v]) + l_tbl.push_back(v); } } b_tbl = treeJump(p); @@ -50,6 +49,6 @@ struct ladder { int bit = __lg(k); v = b_tbl[bit][v], k -= (1 << bit); int leaf = dl[v]; - return l_tbl[leaf][k + d[leaf] - d[v]]; + return l_tbl[idx_l[leaf] + k - d[v]]; } }; diff --git a/library/trees/ladder_decomposition/linear_kth_par.hpp b/library/trees/ladder_decomposition/linear_kth_par.hpp index f0a99f7e..31e1ca68 100644 --- a/library/trees/ladder_decomposition/linear_kth_par.hpp +++ b/library/trees/ladder_decomposition/linear_kth_par.hpp @@ -9,11 +9,11 @@ //! @space O(n) struct linear_kth_par { struct node { - int d, p = -1, idx, dl; - vi lad; + int d, p = -1, dl, idx_j, idx_l; }; vector t; vector j; + vi l_tbl; linear_kth_par(const vector& adj): t(sz(adj)), j(2 * sz(t)) { vi st; @@ -25,7 +25,7 @@ struct linear_kth_par { }; auto dfs = [&](auto&& self, int v) -> void { st.push_back(v); - t[v].idx = pos, t[v].dl = v; + t[v].idx_j = pos, t[v].dl = v; add_j(); for (int u : adj[v]) if (u != t[v].p) { @@ -40,12 +40,10 @@ struct linear_kth_par { rep(i, 0, sz(t)) { if (t[i].p == -1) dfs(dfs, i); if (t[i].p == -1 || t[t[i].p].dl != t[i].dl) { - int leaf = t[i].dl; - vi& lad = t[leaf].lad; - lad.resize( - min((t[leaf].d - t[i].d) * 2, t[leaf].d + 1), - leaf); - rep(k, 1, sz(lad)) lad[k] = t[lad[k - 1]].p; + int v = t[i].dl, len = (t[v].d - t[i].d) * 2; + t[v].idx_l = sz(l_tbl) + t[v].d; + for (; v != -1 && len--; v = t[v].p) + l_tbl.push_back(v); } } } @@ -57,9 +55,9 @@ struct linear_kth_par { case 2: return t[t[v].p].p; default: int i = 1 << __lg(k / 3); - auto [j1, j2] = j[(t[v].idx & -i) | i]; - int leaf = t[t[v].d - t[j2].d <= k ? j2 : j1].dl; - return t[leaf].lad[k + t[leaf].d - t[v].d]; + auto [j1, j2] = j[(t[v].idx_j & -i) | i]; + int up = t[v].d - t[j2].d <= k ? j2 : j1; + return l_tbl[t[t[up].dl].idx_l + k - t[v].d]; } } };