From 41b4a59a665a874094bd41c78e209ea778e6f92a Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 28 Aug 2025 13:00:32 -0600 Subject: [PATCH 1/6] shallowest decomp tree --- library/trees/shallowest_decomp_tree.hpp | 25 +++++++++++ .../shallowest_aizu_tree_height.test.cpp | 45 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 library/trees/shallowest_decomp_tree.hpp create mode 100644 tests/library_checker_aizu_tests/trees/shallowest_aizu_tree_height.test.cpp diff --git a/library/trees/shallowest_decomp_tree.hpp b/library/trees/shallowest_decomp_tree.hpp new file mode 100644 index 00000000..782fd9df --- /dev/null +++ b/library/trees/shallowest_decomp_tree.hpp @@ -0,0 +1,25 @@ +#pragma once +void shallowest(auto& adj, auto f) { + vector order(bit_width(size(adj))); + auto dfs = [&](auto&& self, int v, int p) -> int { + int once = 0, twice = 0; + for (int u : adj[v]) + if (u != p) { + int dp = self(self, u, v); + twice |= once & dp, once |= dp; + } + auto dp = (once | (bit_ceil(twice + 1u) - 1)) + 1; + order[countr_zero(dp)].push_back(v); + return dp; + }; + dfs(dfs, 0, 0); + for (auto& vec : order | views::reverse) + for (int cent : vec) { + f(cent); + for (int v : adj[cent]) { + iter_swap(ranges::find(adj[v], cent), + rbegin(adj[v])); + adj[v].pop_back(); + } + } +} diff --git a/tests/library_checker_aizu_tests/trees/shallowest_aizu_tree_height.test.cpp b/tests/library_checker_aizu_tests/trees/shallowest_aizu_tree_height.test.cpp new file mode 100644 index 00000000..f3823495 --- /dev/null +++ b/tests/library_checker_aizu_tests/trees/shallowest_aizu_tree_height.test.cpp @@ -0,0 +1,45 @@ +#define PROBLEM \ + "https://onlinejudge.u-aizu.ac.jp/problems/GRL_5_B" +#include "../template.hpp" +#include "../../../library/trees/shallowest_decomp_tree.hpp" +int main() { + cin.tie(0)->sync_with_stdio(0); + int n; + cin >> n; + vector> adj(n); + map, int> weight; + for (int i = 0; i < n - 1; i++) { + int u, v, w; + cin >> u >> v >> w; + weight[{u, v}] = w; + weight[{v, u}] = w; + adj[u].push_back(v); + adj[v].push_back(u); + } + vector res(n); + shallowest(adj, [&](int cent) { + int lowest = 0; + int curr_lowest = 0; + auto dfs = [&](auto&& self, int v, int p, + int height) -> void { + res[v] = max(res[v], height + lowest); + res[cent] = max(res[cent], height); + curr_lowest = max(curr_lowest, height); + for (int u : adj[v]) + if (u != p) + self(self, u, v, height + weight[{u, v}]); + }; + for (int v : adj[cent]) { + curr_lowest = 0; + dfs(dfs, v, cent, weight[{v, cent}]); + lowest = max(lowest, curr_lowest); + } + lowest = 0; + for (int v : adj[cent] | views::reverse) { + curr_lowest = 0; + dfs(dfs, v, cent, weight[{v, cent}]); + lowest = max(lowest, curr_lowest); + } + }); + for (int i = 0; i < n; i++) cout << res[i] << '\n'; +} From ff725530881eb8a7193a8fce90b1d60640c02179 Mon Sep 17 00:00:00 2001 From: GitHub Date: Thu, 28 Aug 2025 19:01:59 +0000 Subject: [PATCH 2/6] [auto-verifier] verify commit 41b4a59a665a874094bd41c78e209ea778e6f92a --- .verify-helper/timestamps.remote.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 4562a8fe..908037ba 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -144,5 +144,6 @@ "tests/library_checker_aizu_tests/trees/kth_path_tree_lift.test.cpp": "2025-08-14 10:27:46 -0600", "tests/library_checker_aizu_tests/trees/lca_all_methods_aizu.test.cpp": "2025-08-21 12:17:27 -0600", "tests/library_checker_aizu_tests/trees/lca_all_methods_lib_checker.test.cpp": "2025-08-21 12:17:27 -0600", +"tests/library_checker_aizu_tests/trees/shallowest_aizu_tree_height.test.cpp": "2025-08-28 13:00:32 -0600", "tests/library_checker_aizu_tests/trees/subtree_isomorphism.test.cpp": "2025-08-14 10:27:46 -0600" } \ No newline at end of file From b04851bbe9962f3b2fac6ca2461eb73c5a338e0e Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 28 Aug 2025 13:09:33 -0600 Subject: [PATCH 3/6] nits --- library/trees/shallowest_decomp_tree.hpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/library/trees/shallowest_decomp_tree.hpp b/library/trees/shallowest_decomp_tree.hpp index 782fd9df..998d30d3 100644 --- a/library/trees/shallowest_decomp_tree.hpp +++ b/library/trees/shallowest_decomp_tree.hpp @@ -1,4 +1,12 @@ #pragma once +//! https://codeforces.com/blog/entry/125018 +//! @code +//! vector> adj(n); +//! shallowest(adj, [&](int cent) { +//! }); +//! @endcode +//! @time O(n log n) +//! @space O(n) void shallowest(auto& adj, auto f) { vector order(bit_width(size(adj))); auto dfs = [&](auto&& self, int v, int p) -> int { @@ -13,13 +21,11 @@ void shallowest(auto& adj, auto f) { return dp; }; dfs(dfs, 0, 0); - for (auto& vec : order | views::reverse) - for (int cent : vec) { - f(cent); - for (int v : adj[cent]) { - iter_swap(ranges::find(adj[v], cent), - rbegin(adj[v])); - adj[v].pop_back(); - } + for (const auto& vec : order | views::reverse) + for (int v : vec) { + f(v); + for (int u : adj[v]) + iter_swap(ranges::find(adj[u], v), rbegin(adj[u])), + adj[u].pop_back(); } } From c71b50988d8b7984ca8ef1c6d79cccdad4a86ca1 Mon Sep 17 00:00:00 2001 From: GitHub Date: Thu, 28 Aug 2025 19:10:52 +0000 Subject: [PATCH 4/6] [auto-verifier] verify commit b04851bbe9962f3b2fac6ca2461eb73c5a338e0e --- .verify-helper/timestamps.remote.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 908037ba..924faead 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -144,6 +144,6 @@ "tests/library_checker_aizu_tests/trees/kth_path_tree_lift.test.cpp": "2025-08-14 10:27:46 -0600", "tests/library_checker_aizu_tests/trees/lca_all_methods_aizu.test.cpp": "2025-08-21 12:17:27 -0600", "tests/library_checker_aizu_tests/trees/lca_all_methods_lib_checker.test.cpp": "2025-08-21 12:17:27 -0600", -"tests/library_checker_aizu_tests/trees/shallowest_aizu_tree_height.test.cpp": "2025-08-28 13:00:32 -0600", +"tests/library_checker_aizu_tests/trees/shallowest_aizu_tree_height.test.cpp": "2025-08-28 13:09:33 -0600", "tests/library_checker_aizu_tests/trees/subtree_isomorphism.test.cpp": "2025-08-14 10:27:46 -0600" } \ No newline at end of file From 25fc1d7f6ab93bb2c4c72162012dea03c2dce5d4 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 28 Aug 2025 13:12:36 -0600 Subject: [PATCH 5/6] revert constexpr -> const as it was causing build issues --- library/convolution/gcd_convolution.hpp | 2 +- library/convolution/lcm_convolution.hpp | 2 +- library/data_structures/seg_tree_uncommon/implicit.hpp | 2 +- library/math/fibonacci.hpp | 2 +- library/math/mod_int.hpp | 2 +- library/math/n_choose_k/grow.hpp | 2 +- library/math/n_choose_k/pascals_identity.hpp | 2 +- library/math/partitions.hpp | 2 +- .../handmade_tests/mod_int.test.cpp | 4 ++-- .../math/binary_exponentiation_mod.test.cpp | 4 ++-- tests/library_checker_aizu_tests/math/count_paths.test.cpp | 4 ++-- .../math/mod_int_derangement.test.cpp | 4 ++-- .../math/mod_int_n_choose_k.test.cpp | 4 ++-- .../math/mod_int_tetration.test.cpp | 4 ++-- tests/library_checker_aizu_tests/math/n_choose_k.test.cpp | 4 ++-- 15 files changed, 22 insertions(+), 22 deletions(-) diff --git a/library/convolution/gcd_convolution.hpp b/library/convolution/gcd_convolution.hpp index 07091fc2..6af1f424 100644 --- a/library/convolution/gcd_convolution.hpp +++ b/library/convolution/gcd_convolution.hpp @@ -7,7 +7,7 @@ //! for all pairs (i,j) where gcd(i,j)==k //! @time O(n log n) //! @space O(n) -constexpr int mod = 998'244'353; +const int mod = 998'244'353; vi gcd_convolution(const vi& a, const vi& b) { int n = sz(a); vi c(n); diff --git a/library/convolution/lcm_convolution.hpp b/library/convolution/lcm_convolution.hpp index 498c15c6..85449dc2 100644 --- a/library/convolution/lcm_convolution.hpp +++ b/library/convolution/lcm_convolution.hpp @@ -7,7 +7,7 @@ //! for all pairs (i,j) where lcm(i,j)==k //! @time O(n log n) //! @space O(n) -constexpr int mod = 998'244'353; +const int mod = 998'244'353; vi lcm_convolution(const vi& a, const vi& b) { int n = sz(a); vector sum_a(n), sum_b(n); diff --git a/library/data_structures/seg_tree_uncommon/implicit.hpp b/library/data_structures/seg_tree_uncommon/implicit.hpp index 76a6570b..e9089599 100644 --- a/library/data_structures/seg_tree_uncommon/implicit.hpp +++ b/library/data_structures/seg_tree_uncommon/implicit.hpp @@ -8,7 +8,7 @@ template struct implicit_seg_tree { if (l[0] == r[0]) return {l[0], l[1] + r[1]}; return min(l, r); } - static constexpr dt unit{LLONG_MAX, 0LL}; + static const dt unit{LLONG_MAX, 0LL}; struct node { dt num; ll lazy = 0; diff --git a/library/math/fibonacci.hpp b/library/math/fibonacci.hpp index c2c36ba8..f0de2014 100644 --- a/library/math/fibonacci.hpp +++ b/library/math/fibonacci.hpp @@ -11,7 +11,7 @@ //! @endcode //! @time O(log n) //! @space O(log n) -constexpr int mod = 998'244'353; +const int mod = 998'244'353; array fib(ll n) { if (n == 0) return {0LL, 1LL}; auto [x, y] = fib(n >> 1); diff --git a/library/math/mod_int.hpp b/library/math/mod_int.hpp index ab7e2a9f..a2fa8818 100644 --- a/library/math/mod_int.hpp +++ b/library/math/mod_int.hpp @@ -1,5 +1,5 @@ #pragma once -constexpr int mod = 998244353; +const int mod = 998244353; //! https://github.com/kth-competitive-programming/kactl/blob/main/content/number-theory/ModularArithmetic.h //! https://codeforces.com/blog/entry/122714 struct mint { diff --git a/library/math/n_choose_k/grow.hpp b/library/math/n_choose_k/grow.hpp index a52e8ea6..563ddf91 100644 --- a/library/math/n_choose_k/grow.hpp +++ b/library/math/n_choose_k/grow.hpp @@ -1,5 +1,5 @@ #pragma once -constexpr int mod = 17; //!< must be prime +const int mod = 17; //!< must be prime struct comb { ll inv = 1, fact = 1, inv_fact = 1; }; diff --git a/library/math/n_choose_k/pascals_identity.hpp b/library/math/n_choose_k/pascals_identity.hpp index fcf5ce22..1a0b412b 100644 --- a/library/math/n_choose_k/pascals_identity.hpp +++ b/library/math/n_choose_k/pascals_identity.hpp @@ -1,5 +1,5 @@ #pragma once -constexpr int mod = 17; //!< composite ok +const int mod = 17; //!< composite ok vector> ch(1010); //!< ch[n][k] = n choose k rep(i, 0, sz(ch)) { ch[i].resize(i + 1, 1); diff --git a/library/math/partitions.hpp b/library/math/partitions.hpp index 51771e15..822ed670 100644 --- a/library/math/partitions.hpp +++ b/library/math/partitions.hpp @@ -1,5 +1,5 @@ #pragma once -constexpr int mod = 998'244'353; +const int mod = 998'244'353; //! https://oeis.org/A000041 //! @code //! auto p = partitions(n); diff --git a/tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp index 66a61217..4520bab2 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp @@ -5,9 +5,9 @@ #include "../../../kactl/content/number-theory/euclid.h" // trick to remove const so I can use arbitrary prime mode // here -#define constexpr ; +#define const ; #include "../../../library/math/mod_int_pow.hpp" -#undef constexpr +#undef const int main() { cin.tie(0)->sync_with_stdio(0); mint val; diff --git a/tests/library_checker_aizu_tests/math/binary_exponentiation_mod.test.cpp b/tests/library_checker_aizu_tests/math/binary_exponentiation_mod.test.cpp index 86fed423..211821ce 100644 --- a/tests/library_checker_aizu_tests/math/binary_exponentiation_mod.test.cpp +++ b/tests/library_checker_aizu_tests/math/binary_exponentiation_mod.test.cpp @@ -3,9 +3,9 @@ #include "../template.hpp" // trick to remove const so I can use arbitrary prime mode // here -#define constexpr ; +#define const ; #include "../../../library/math/mod_int_pow.hpp" -#undef constexpr +#undef const int main() { cin.tie(0)->sync_with_stdio(0); mod = 1'000'000'007; diff --git a/tests/library_checker_aizu_tests/math/count_paths.test.cpp b/tests/library_checker_aizu_tests/math/count_paths.test.cpp index b5ce8619..7f8e5220 100644 --- a/tests/library_checker_aizu_tests/math/count_paths.test.cpp +++ b/tests/library_checker_aizu_tests/math/count_paths.test.cpp @@ -1,10 +1,10 @@ #define PROBLEM \ "https://judge.yosupo.jp/problem/number_of_increasing_sequences_between_two_sequences" #include "../template.hpp" -#define constexpr ; +#define const ; #define mod mod_different_name #include "../../../library/math/n_choose_k/grow.hpp" -#undef constexpr +#undef const #undef mod #define mod mod_not_using #define modpow modpow_not_using diff --git a/tests/library_checker_aizu_tests/math/mod_int_derangement.test.cpp b/tests/library_checker_aizu_tests/math/mod_int_derangement.test.cpp index f2e9145f..3ccb9ad6 100644 --- a/tests/library_checker_aizu_tests/math/mod_int_derangement.test.cpp +++ b/tests/library_checker_aizu_tests/math/mod_int_derangement.test.cpp @@ -3,9 +3,9 @@ #include "../template.hpp" // trick to remove const so I can use arbitrary prime mode // here -#define constexpr ; +#define const ; #include "../../../library/math/mod_int.hpp" -#undef constexpr +#undef const int main() { cin.tie(0)->sync_with_stdio(0); int n; diff --git a/tests/library_checker_aizu_tests/math/mod_int_n_choose_k.test.cpp b/tests/library_checker_aizu_tests/math/mod_int_n_choose_k.test.cpp index 7ab6e71f..aa019a3c 100644 --- a/tests/library_checker_aizu_tests/math/mod_int_n_choose_k.test.cpp +++ b/tests/library_checker_aizu_tests/math/mod_int_n_choose_k.test.cpp @@ -3,9 +3,9 @@ #include "../template.hpp" // trick to remove const so I can use arbitrary prime mode // here -#define constexpr ; +#define const ; #include "../../../library/math/mod_int.hpp" -#undef constexpr +#undef const int main() { cin.tie(0)->sync_with_stdio(0); int t; diff --git a/tests/library_checker_aizu_tests/math/mod_int_tetration.test.cpp b/tests/library_checker_aizu_tests/math/mod_int_tetration.test.cpp index e1dec8db..3ece33ad 100644 --- a/tests/library_checker_aizu_tests/math/mod_int_tetration.test.cpp +++ b/tests/library_checker_aizu_tests/math/mod_int_tetration.test.cpp @@ -4,9 +4,9 @@ #include "../../../library/math/totient.hpp" // trick to remove const so I can use arbitrary prime mode // here -#define constexpr ; +#define const ; #include "../../../library/math/mod_int_pow.hpp" -#undef constexpr +#undef const int mod_int_tetration(int b, int e, int local_mod) { if (local_mod == 1) return 0; if (b == 0) return (e + 1) % 2 % local_mod; diff --git a/tests/library_checker_aizu_tests/math/n_choose_k.test.cpp b/tests/library_checker_aizu_tests/math/n_choose_k.test.cpp index 1421f508..2c031f00 100644 --- a/tests/library_checker_aizu_tests/math/n_choose_k.test.cpp +++ b/tests/library_checker_aizu_tests/math/n_choose_k.test.cpp @@ -3,9 +3,9 @@ #include "../template.hpp" // trick to remove const so I can use arbitrary prime mode // here -#define constexpr ; +#define const ; #include "../../../library/math/n_choose_k/n_choose_k.hpp" -#undef constexpr +#undef const int main() { cin.tie(0)->sync_with_stdio(0); int num_tests; From 52dffa6d8df283a2c82884e4e12cfde30126bf5c Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 28 Aug 2025 13:15:34 -0600 Subject: [PATCH 6/6] fix --- library/data_structures/seg_tree_uncommon/implicit.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/data_structures/seg_tree_uncommon/implicit.hpp b/library/data_structures/seg_tree_uncommon/implicit.hpp index e9089599..f60d7ddf 100644 --- a/library/data_structures/seg_tree_uncommon/implicit.hpp +++ b/library/data_structures/seg_tree_uncommon/implicit.hpp @@ -8,7 +8,7 @@ template struct implicit_seg_tree { if (l[0] == r[0]) return {l[0], l[1] + r[1]}; return min(l, r); } - static const dt unit{LLONG_MAX, 0LL}; + const dt unit{LLONG_MAX, 0LL}; struct node { dt num; ll lazy = 0;