From b9ac2cf1da5757e484eeec70c3490679f2476c41 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 27 Feb 2026 11:50:42 -0700 Subject: [PATCH 01/10] lots of nits --- library/dsu/kruskal_tree.hpp | 6 ++--- library/dsu/range_parallel_dsu.hpp | 25 ++++++++---------- .../range_parallel_equivalence_classes.hpp | 26 ++++++++++++------- .../{data_structures => dsu}/dsu.test.cpp | 0 .../dsu_bipartite.test.cpp | 0 .../kruskal_tree_aizu.test.cpp | 0 .../line_tree_aizu.test.cpp | 0 .../line_tree_lib_checker.test.cpp | 0 .../range_parallel_dsu.test.cpp | 9 +++---- 9 files changed, 33 insertions(+), 33 deletions(-) rename tests/library_checker_aizu_tests/{data_structures => dsu}/dsu.test.cpp (100%) rename tests/library_checker_aizu_tests/{data_structures => dsu}/dsu_bipartite.test.cpp (100%) rename tests/library_checker_aizu_tests/{data_structures => dsu}/kruskal_tree_aizu.test.cpp (100%) rename tests/library_checker_aizu_tests/{data_structures => dsu}/line_tree_aizu.test.cpp (100%) rename tests/library_checker_aizu_tests/{data_structures => dsu}/line_tree_lib_checker.test.cpp (100%) rename tests/library_checker_aizu_tests/{data_structures => dsu}/range_parallel_dsu.test.cpp (87%) diff --git a/library/dsu/kruskal_tree.hpp b/library/dsu/kruskal_tree.hpp index 745517c22..d4e7890f4 100644 --- a/library/dsu/kruskal_tree.hpp +++ b/library/dsu/kruskal_tree.hpp @@ -7,11 +7,9 @@ struct kr_tree { vi p; vector adj; kr_tree(int n): id(n), p(2 * n, -1), adj(2 * n) {} - int find(int v) { - return p[v] < 0 ? v : p[v] = find(p[v]); - } + int f(int v) { return p[v] < 0 ? v : p[v] = f(p[v]); } bool join(int u, int v) { - if ((u = find(u)) == (v = find(v))) return 0; + if ((u = f(u)) == (v = f(v))) return 0; return adj[p[u] = p[v] = id++] = {u, v}, 1; } }; diff --git a/library/dsu/range_parallel_dsu.hpp b/library/dsu/range_parallel_dsu.hpp index 0a10ec587..e17c8188a 100644 --- a/library/dsu/range_parallel_dsu.hpp +++ b/library/dsu/range_parallel_dsu.hpp @@ -1,31 +1,28 @@ #pragma once #include "dsu.hpp" -//! Given l1,l2,len; joins (l1,l2), (l1+1,l2+1), -//! ..., (l1+len-1,l2+len-1) +//! Given u,v,len; joins (u,v), (u+1,v+1), +//! ..., (u+len-1,v+len-1) //! `f` is called at most n-1 times //! @time O(n*log(n)*\alpha(n) + q) //! @space O(n log n) struct rp_dsu { vector dsus; rp_dsu(int n): dsus(bit_width(unsigned(n)), DSU(n)) {} - void join(int l1, int l2, int len, const auto& f) { - if (len == 0) return; - int lg = __lg(len); - join_impl(lg, l1, l2, f); - join_impl(lg, l1 + len - (1 << lg), - l2 + len - (1 << lg), f); + void join(int u, int v, int len, const auto& f) { + int i = __lg(len); + join(u, v, f, i); + join(u + len - (1 << i), v + len - (1 << i), f, i); } - void join_impl(int lvl, int u, int v, const auto& f) { - if (lvl == 0) { + void join(int u, int v, const auto& f, int i) { + if (i == 0) { u = dsus[0].f(u); v = dsus[0].f(v); if (!dsus[0].join(v, u)) return; int w = dsus[0].f(u); return f(w, u ^ v ^ w); } - if (!dsus[lvl].join(u, v)) return; - join_impl(lvl - 1, u, v, f); - join_impl(lvl - 1, u + (1 << (lvl - 1)), - v + (1 << (lvl - 1)), f); + if (!dsus[i].join(u, v)) return; + join(u, v, f, i - 1); + join(u + (1 << (i - 1)), v + (1 << (i - 1)), f, i - 1); } }; diff --git a/library/dsu/range_parallel_equivalence_classes.hpp b/library/dsu/range_parallel_equivalence_classes.hpp index 3a5796eb1..fdbcf1c0f 100644 --- a/library/dsu/range_parallel_equivalence_classes.hpp +++ b/library/dsu/range_parallel_equivalence_classes.hpp @@ -1,17 +1,23 @@ #pragma once #include "dsu.hpp" -//! Given triplets (l1,l2,len); joins (l1,l2), -//! (l1+1,l2+1), ..., (l1+len-1,l2+len-1) +//! @code +//! vector> joins(n + 1); +//! joins[len].emplace_back(u, v); +//! // it does: +//! // dsu.join(u + 0, v + 0); +//! // dsu.join(u + 1, v + 1); +//! // dsu.join(u + 2, v + 2); +//! // ... +//! // dsu.join(u + len - 1, v + len - 1); +//! DSU dsu = get_rp_dsu(joins, n); +//! @endcode //! @time O((n + q) * \alpha(n)) //! @space O(n + q) -DSU get_rp_dsu(const vector>& rests, int n) { - vector> rests_by_len(n + 1); - for (auto [l1, l2, len] : rests) - rests_by_len[len].emplace_back(l1, l2); +DSU get_rp_dsu(vector>& joins, int n) { DSU dsu(n); - for (int len = n; len > 0; len--) - for (auto [l1, l2] : rests_by_len[len]) - if (dsu.join(l1, l2)) - rests_by_len[len - 1].emplace_back(l1 + 1, l2 + 1); + for (int i = n; i; i--) + for (auto [u, v] : joins[i]) + if (dsu.join(u, v)) + joins[i - 1].emplace_back(u + 1, v + 1); return dsu; } diff --git a/tests/library_checker_aizu_tests/data_structures/dsu.test.cpp b/tests/library_checker_aizu_tests/dsu/dsu.test.cpp similarity index 100% rename from tests/library_checker_aizu_tests/data_structures/dsu.test.cpp rename to tests/library_checker_aizu_tests/dsu/dsu.test.cpp diff --git a/tests/library_checker_aizu_tests/data_structures/dsu_bipartite.test.cpp b/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp similarity index 100% rename from tests/library_checker_aizu_tests/data_structures/dsu_bipartite.test.cpp rename to tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp diff --git a/tests/library_checker_aizu_tests/data_structures/kruskal_tree_aizu.test.cpp b/tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp similarity index 100% rename from tests/library_checker_aizu_tests/data_structures/kruskal_tree_aizu.test.cpp rename to tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp diff --git a/tests/library_checker_aizu_tests/data_structures/line_tree_aizu.test.cpp b/tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp similarity index 100% rename from tests/library_checker_aizu_tests/data_structures/line_tree_aizu.test.cpp rename to tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp diff --git a/tests/library_checker_aizu_tests/data_structures/line_tree_lib_checker.test.cpp b/tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp similarity index 100% rename from tests/library_checker_aizu_tests/data_structures/line_tree_lib_checker.test.cpp rename to tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp diff --git a/tests/library_checker_aizu_tests/data_structures/range_parallel_dsu.test.cpp b/tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp similarity index 87% rename from tests/library_checker_aizu_tests/data_structures/range_parallel_dsu.test.cpp rename to tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp index b4b465977..9e67c7d33 100644 --- a/tests/library_checker_aizu_tests/data_structures/range_parallel_dsu.test.cpp +++ b/tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp @@ -18,17 +18,16 @@ int main() { ans = (ans + 1LL * x[u] * x[v]) % mod; x[u] = (x[u] + x[v]) % mod; }; - vector> queries; - queries.reserve(q); + vector> joins(n + 1); for (int qq = 0; qq < q; qq++) { int k, a, b; cin >> k >> a >> b; - dsu.join(a, b, k, f); - queries.push_back({a, b, k}); + if (k) dsu.join(a, b, k, f); + joins[k].emplace_back(a, b); cout << ans << '\n'; if (qq == 0 || qq == 1 || qq == 10 || qq == 1000 || qq == 100'000 || qq == q - 1) { - auto uf = get_rp_dsu(queries, n); + auto uf = get_rp_dsu(joins, n); vi sums(n); int offline_ans = 0; for (int i = 0; i < n; i++) { From 9de6cd92de9a74e77c43cfd310c634f5d22e1d71 Mon Sep 17 00:00:00 2001 From: GitHub Date: Fri, 27 Feb 2026 18:55:07 +0000 Subject: [PATCH 02/10] [auto-verifier] verify commit b9ac2cf1da5757e484eeec70c3490679f2476c41 --- .verify-helper/timestamps.remote.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index ca5b0c1e7..71cfc9633 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -18,26 +18,20 @@ "tests/library_checker_aizu_tests/data_structures/disjoint_rmq_inc_lines.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/disjoint_rmq_inc_sum.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/distinct_query.test.cpp": "2026-01-18 11:15:41 +0000", -"tests/library_checker_aizu_tests/data_structures/dsu.test.cpp": "2026-01-22 10:08:22 -0700", -"tests/library_checker_aizu_tests/data_structures/dsu_bipartite.test.cpp": "2026-01-18 02:20:40 +0000", "tests/library_checker_aizu_tests/data_structures/implicit_seg_tree.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/kd_bit_1d.test.cpp": "2026-02-19 18:06:52 -0700", -"tests/library_checker_aizu_tests/data_structures/kruskal_tree_aizu.test.cpp": "2026-01-18 02:20:40 +0000", "tests/library_checker_aizu_tests/data_structures/kth_smallest_pst.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2026-02-04 02:50:53 +0000", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree.test.cpp": "2026-01-23 04:31:29 +0000", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_constructor.test.cpp": "2026-01-23 04:31:29 +0000", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_inc.test.cpp": "2026-02-05 13:02:29 -0700", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_inc_constructor.test.cpp": "2026-02-05 13:02:29 -0700", -"tests/library_checker_aizu_tests/data_structures/line_tree_aizu.test.cpp": "2026-01-18 11:15:41 +0000", -"tests/library_checker_aizu_tests/data_structures/line_tree_lib_checker.test.cpp": "2026-01-18 02:20:40 +0000", "tests/library_checker_aizu_tests/data_structures/merge_sort_tree.test.cpp": "2026-01-18 11:04:58 +0000", "tests/library_checker_aizu_tests/data_structures/mode_query.test.cpp": "2026-01-18 02:20:40 +0000", "tests/library_checker_aizu_tests/data_structures/permutation_tree.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/persistent_queue_tree.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/persistent_seg_tree.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/pq_ds_undo_sliding_window.test.cpp": "2026-01-18 02:20:40 +0000", -"tests/library_checker_aizu_tests/data_structures/range_parallel_dsu.test.cpp": "2026-01-22 10:08:22 -0700", "tests/library_checker_aizu_tests/data_structures/rmq_linear.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/rmq_sparse_table.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/data_structures/rmq_sparse_table_inc.test.cpp": "2026-01-18 11:15:41 +0000", @@ -47,6 +41,12 @@ "tests/library_checker_aizu_tests/data_structures/simple_tree_inc_walk.test.cpp": "2026-02-16 16:56:58 -0700", "tests/library_checker_aizu_tests/data_structures/simple_tree_line.test.cpp": "2026-02-14 20:58:21 +0000", "tests/library_checker_aizu_tests/data_structures/simple_tree_walk.test.cpp": "2026-02-14 20:58:21 +0000", +"tests/library_checker_aizu_tests/dsu/dsu.test.cpp": "2026-02-27 11:50:42 -0700", +"tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp": "2026-02-27 11:50:42 -0700", +"tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp": "2026-02-27 11:50:42 -0700", +"tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp": "2026-02-27 11:50:42 -0700", +"tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp": "2026-02-27 11:50:42 -0700", +"tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp": "2026-02-27 11:50:42 -0700", "tests/library_checker_aizu_tests/flow/dinic_aizu.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/hungarian.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/min_cost_max_flow.test.cpp": "2024-12-05 10:41:42 -0600", From 0a7faa9aadc7d5c3bfb973847a016665dbc5fd58 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 27 Feb 2026 11:56:18 -0700 Subject: [PATCH 03/10] more nits --- library/dsu/line_tree.hpp | 14 ++++++-------- .../dsu/line_tree_aizu.test.cpp | 2 +- .../dsu/line_tree_lib_checker.test.cpp | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/library/dsu/line_tree.hpp b/library/dsu/line_tree.hpp index 11cc34bed..7093a7b7b 100644 --- a/library/dsu/line_tree.hpp +++ b/library/dsu/line_tree.hpp @@ -4,14 +4,14 @@ //! ranges::sort(w_eds); //! line_tree lt(n); //! for (auto [w, u, v] : w_eds) lt.join(u, v); -//! for (int v = lt.find(0); v != -1;) { +//! for (int v = lt.f(0); v != -1;) { //! auto [next, e_id] = lt.edge[v]; //! int w = w_eds[e_id][0]; //! // //! v = next; //! } //! @endcode -//! lt.find(v) = head of linked list +//! lt.f(v) = head of linked list //! of component containing v //! @time O(n + m * \alpha(n)) //! @space O(n + m) @@ -22,16 +22,14 @@ struct line_tree { line_tree(int n): p(n, -1), last(n), edge(n, {-1, -1}) { iota(all(last), 0); } - int size(int v) { return -p[find(v)]; } - int find(int v) { - return p[v] < 0 ? v : p[v] = find(p[v]); - } + int size(int v) { return -p[f(v)]; } + int f(int v) { return p[v] < 0 ? v : p[v] = f(p[v]); } bool join(int u, int v) { - u = find(u), v = find(v), id++; + u = f(u), v = f(v), id++; if (u == v) return 0; if (p[u] < p[v]) swap(u, v); p[v] += p[u], p[u] = v; - edge[exchange(last[v], last[u])] = {u, id - 1}; + edge[last[v]] = {u, id - 1}, last[v] = last[u]; return 1; } }; diff --git a/tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp b/tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp index 9efbd9ed3..e7dd516d5 100644 --- a/tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp +++ b/tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp @@ -28,7 +28,7 @@ int main() { int mst_sum = 0; vector edge_weights; vector to_time(n); - for (int v = lt.find(0), timer = 1; + for (int v = lt.f(0), timer = 1; lt.edge[v] != pii{-1, -1}; v = lt.edge[v].first, timer++) { edge_weights.push_back(w_eds[lt.edge[v].second][0]); diff --git a/tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp b/tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp index 65b3c5e44..535f686b3 100644 --- a/tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp +++ b/tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp @@ -22,7 +22,7 @@ int main() { assert(lt.size(0) == n); int64_t cost = 0; vector ids; - for (int v = lt.find(0); lt.edge[v].first != -1; + for (int v = lt.f(0); lt.edge[v].first != -1; v = lt.edge[v].first) { ids.push_back(w_eds[lt.edge[v].second][0]); cost += weights[w_eds[lt.edge[v].second][0]]; From 2cba68824e72ca048c1c2e62af92af648030dda0 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 27 Feb 2026 11:58:10 -0700 Subject: [PATCH 04/10] even more nits --- library/dsu/dsu_bipartite.hpp | 13 +++++-------- .../dsu/dsu_bipartite.test.cpp | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/library/dsu/dsu_bipartite.hpp b/library/dsu/dsu_bipartite.hpp index 8cbb199e6..3c385dcab 100644 --- a/library/dsu/dsu_bipartite.hpp +++ b/library/dsu/dsu_bipartite.hpp @@ -7,14 +7,14 @@ struct dsu_bipartite { vi p, is_bi, parity; dsu_bipartite(int n): num_sets(n), p(n, -1), is_bi(n, 1), parity(n) {} - int find(int v) { + int f(int v) { if (p[v] < 0) return v; - int root = find(p[v]); + int root = f(p[v]); parity[v] ^= parity[p[v]]; return p[v] = root; } bool join(int u, int v) { - int root_u = find(u), root_v = find(v); + int root_u = f(u), root_v = f(v); if (root_u == root_v) { if (parity[u] == parity[v]) is_bi[root_u] = 0; return 0; @@ -28,9 +28,6 @@ struct dsu_bipartite { p[root_u] += p[root_v], p[root_v] = root_u, num_sets--; return 1; } - int size(int v) { return -p[find(v)]; } - bool same_set(int u, int v) { - return find(u) == find(v); - } - bool is_bipartite(int v) { return is_bi[find(v)]; } + int size(int v) { return -p[f(v)]; } + bool is_bipartite(int v) { return is_bi[f(v)]; } }; diff --git a/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp b/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp index 77b46f82e..cf63bd6c5 100644 --- a/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp +++ b/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp @@ -42,7 +42,7 @@ int main() { dsu.join(u, v); adj[u].push_back(v); adj[v].push_back(u); - } else cout << dsu.same_set(u, v) << '\n'; + } else cout << (dsu.f(u) == dsu.f(v)) << '\n'; if (rnd(0, 20'000) == 0) check(); } check(); From 2cb38e338a790a953155d625a4b3588237edc30c Mon Sep 17 00:00:00 2001 From: GitHub Date: Fri, 27 Feb 2026 19:01:31 +0000 Subject: [PATCH 05/10] [auto-verifier] verify commit 2cba68824e72ca048c1c2e62af92af648030dda0 --- .verify-helper/timestamps.remote.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 71cfc9633..a1c06c3c0 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -42,10 +42,10 @@ "tests/library_checker_aizu_tests/data_structures/simple_tree_line.test.cpp": "2026-02-14 20:58:21 +0000", "tests/library_checker_aizu_tests/data_structures/simple_tree_walk.test.cpp": "2026-02-14 20:58:21 +0000", "tests/library_checker_aizu_tests/dsu/dsu.test.cpp": "2026-02-27 11:50:42 -0700", -"tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp": "2026-02-27 11:50:42 -0700", +"tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp": "2026-02-27 11:58:10 -0700", "tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp": "2026-02-27 11:50:42 -0700", -"tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp": "2026-02-27 11:50:42 -0700", -"tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp": "2026-02-27 11:50:42 -0700", +"tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp": "2026-02-27 11:56:18 -0700", +"tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp": "2026-02-27 11:56:18 -0700", "tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp": "2026-02-27 11:50:42 -0700", "tests/library_checker_aizu_tests/flow/dinic_aizu.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/hungarian.test.cpp": "2024-11-17 14:04:03 -0600", From 854f12e693a80c4fb444f1dba1e9ff39b10a1fa5 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 27 Feb 2026 14:31:41 -0700 Subject: [PATCH 06/10] nits/golf --- library/dsu/range_parallel_dsu.hpp | 15 +++++---------- .../dsu/range_parallel_dsu.test.cpp | 14 ++++++++++---- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/library/dsu/range_parallel_dsu.hpp b/library/dsu/range_parallel_dsu.hpp index e17c8188a..03bd3d4f4 100644 --- a/library/dsu/range_parallel_dsu.hpp +++ b/library/dsu/range_parallel_dsu.hpp @@ -7,22 +7,17 @@ //! @space O(n log n) struct rp_dsu { vector dsus; - rp_dsu(int n): dsus(bit_width(unsigned(n)), DSU(n)) {} + rp_dsu(int n): dsus(bit_width(n + 0u), DSU(n)) {} void join(int u, int v, int len, const auto& f) { int i = __lg(len); join(u, v, f, i); join(u + len - (1 << i), v + len - (1 << i), f, i); } void join(int u, int v, const auto& f, int i) { - if (i == 0) { - u = dsus[0].f(u); - v = dsus[0].f(v); - if (!dsus[0].join(v, u)) return; - int w = dsus[0].f(u); - return f(w, u ^ v ^ w); - } if (!dsus[i].join(u, v)) return; - join(u, v, f, i - 1); - join(u + (1 << (i - 1)), v + (1 << (i - 1)), f, i - 1); + if (i == 0) return f(u, v); + i--; + join(u, v, f, i); + join(u + (1 << i), v + (1 << i), f, i); } }; diff --git a/tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp b/tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp index 9e67c7d33..deb749d14 100644 --- a/tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp +++ b/tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp @@ -9,20 +9,26 @@ int main() { cin.tie(0)->sync_with_stdio(0); int n, q; cin >> n >> q; - rp_dsu dsu(n); + rp_dsu r_dsu(n); vi y(n); for (int i = 0; i < n; i++) cin >> y[i]; vi x = y; int ans = 0; + DSU dsu(n); auto f = [&](int u, int v) { - ans = (ans + 1LL * x[u] * x[v]) % mod; - x[u] = (x[u] + x[v]) % mod; + u = dsu.f(u); + v = dsu.f(v); + assert(dsu.join(u, v)); + int root = dsu.f(u); + int other = root ^ u ^ v; + ans = (ans + 1LL * x[root] * x[other]) % mod; + x[root] = (x[root] + x[other]) % mod; }; vector> joins(n + 1); for (int qq = 0; qq < q; qq++) { int k, a, b; cin >> k >> a >> b; - if (k) dsu.join(a, b, k, f); + if (k) r_dsu.join(a, b, k, f); joins[k].emplace_back(a, b); cout << ans << '\n'; if (qq == 0 || qq == 1 || qq == 10 || qq == 1000 || From 0858cb3c5b9462a2e50b4e95b68efef22502d8cc Mon Sep 17 00:00:00 2001 From: GitHub Date: Fri, 27 Feb 2026 21:33:52 +0000 Subject: [PATCH 07/10] [auto-verifier] verify commit 854f12e693a80c4fb444f1dba1e9ff39b10a1fa5 --- .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 a1c06c3c0..94a38dc02 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -46,7 +46,7 @@ "tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp": "2026-02-27 11:50:42 -0700", "tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp": "2026-02-27 11:56:18 -0700", "tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp": "2026-02-27 11:56:18 -0700", -"tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp": "2026-02-27 11:50:42 -0700", +"tests/library_checker_aizu_tests/dsu/range_parallel_dsu.test.cpp": "2026-02-27 14:31:41 -0700", "tests/library_checker_aizu_tests/flow/dinic_aizu.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/hungarian.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/min_cost_max_flow.test.cpp": "2024-12-05 10:41:42 -0600", From 17a4c2066885739ad5ba3df6d84b1f57062a2ce4 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 27 Feb 2026 15:24:03 -0700 Subject: [PATCH 08/10] update --- library/dsu/dsu_bipartite.hpp | 21 ++++++++----------- .../dsu/dsu_bipartite.test.cpp | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/library/dsu/dsu_bipartite.hpp b/library/dsu/dsu_bipartite.hpp index 3c385dcab..f70095875 100644 --- a/library/dsu/dsu_bipartite.hpp +++ b/library/dsu/dsu_bipartite.hpp @@ -3,10 +3,8 @@ //! DSU with support for parity of path to root for online //! bipartite check struct dsu_bipartite { - int num_sets; vi p, is_bi, parity; - dsu_bipartite(int n): - num_sets(n), p(n, -1), is_bi(n, 1), parity(n) {} + dsu_bipartite(int n): p(n, -1), is_bi(n, 1), parity(n) {} int f(int v) { if (p[v] < 0) return v; int root = f(p[v]); @@ -15,17 +13,16 @@ struct dsu_bipartite { } bool join(int u, int v) { int root_u = f(u), root_v = f(v); - if (root_u == root_v) { - if (parity[u] == parity[v]) is_bi[root_u] = 0; + int new_parity = parity[v] ^ parity[u]; + u = root_u, v = root_v; + if (u == v) { + is_bi[u] &= new_parity; return 0; } - if (p[root_u] > p[root_v]) { - swap(u, v); - swap(root_u, root_v); - } - is_bi[root_u] &= is_bi[root_v]; - parity[root_v] = parity[v] ^ 1 ^ parity[u]; - p[root_u] += p[root_v], p[root_v] = root_u, num_sets--; + if (p[u] > p[v]) swap(u, v); + is_bi[u] &= is_bi[v]; + parity[v] = new_parity ^ 1; + p[u] += p[v], p[v] = u; return 1; } int size(int v) { return -p[f(v)]; } diff --git a/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp b/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp index cf63bd6c5..9dd79a4de 100644 --- a/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp +++ b/tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp @@ -43,7 +43,7 @@ int main() { adj[u].push_back(v); adj[v].push_back(u); } else cout << (dsu.f(u) == dsu.f(v)) << '\n'; - if (rnd(0, 20'000) == 0) check(); + if (i <= 20 || rnd(0, 20'000) == 0) check(); } check(); return 0; From 409ac6b19c7dedf8ef5bf08715bf7d62d45e5b8e Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 27 Feb 2026 15:24:44 -0700 Subject: [PATCH 09/10] fix --- tests/.config/.cppcheck_suppression_list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/.config/.cppcheck_suppression_list b/tests/.config/.cppcheck_suppression_list index 788b33ca6..854778643 100644 --- a/tests/.config/.cppcheck_suppression_list +++ b/tests/.config/.cppcheck_suppression_list @@ -41,7 +41,7 @@ syntaxError:../library/math/prime_sieve/mobius.hpp:6 syntaxError:../library/trees/lca_rmq/iterate_subtree.hpp:6 knownConditionTrueFalse:../library/strings/suffix_array/suffix_array.hpp:62 knownConditionTrueFalse:../library/strings/suffix_array/suffix_array_short.hpp:34 -knownConditionTrueFalse:../library/dsu/kruskal_tree.hpp:15 +knownConditionTrueFalse:../library/dsu/kruskal_tree.hpp:13 knownConditionTrueFalse:../library/dsu/dsu.hpp:11 constVariable:../kactl/content/numerical/NumberTheoreticTransform.h:30 constVariable:../kactl/content/graph/CompressTree.h:20 From 228f7a221cc89eeabd481a49e8799ff1a69aff5a Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 27 Feb 2026 15:26:24 -0700 Subject: [PATCH 10/10] another fix --- tests/scripts/compile_commented_snippets.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/compile_commented_snippets.sh b/tests/scripts/compile_commented_snippets.sh index 2d9c54b36..3caa3df9e 100755 --- a/tests/scripts/compile_commented_snippets.sh +++ b/tests/scripts/compile_commented_snippets.sh @@ -25,7 +25,7 @@ git submodule update echo "vi rhs;" echo "vector mat;" echo "vector> grid;" - echo "int n,m,k,tl,tr,l,r,l1,r1,l2,r2,s_l,s_r,root_l,root_r,source,sink,total_flow,bccid,u,v,lsz,rsz,cols,cap,num,x,y,i,j,i1,i2,j1,j2;" + echo "int n,m,k,tl,tr,l,r,l1,r1,l2,r2,s_l,s_r,root_l,root_r,source,sink,total_flow,bccid,u,v,lsz,rsz,cols,cap,num,x,y,i,j,i1,i2,j1,j2,len;" } >entire_library_without_main {