diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 4562a8fe..924faead 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: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 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..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 constexpr dt unit{LLONG_MAX, 0LL}; + 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/library/trees/shallowest_decomp_tree.hpp b/library/trees/shallowest_decomp_tree.hpp new file mode 100644 index 00000000..998d30d3 --- /dev/null +++ b/library/trees/shallowest_decomp_tree.hpp @@ -0,0 +1,31 @@ +#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 { + 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 (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(); + } +} 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; 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'; +}