From 8c0af3f31f5e1ff76907270b324a4d4559be55df Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 6 Mar 2026 17:30:22 -0700 Subject: [PATCH 01/10] first draft of walk for xor basis --- library/math/matrix_related/xor_basis_ordered.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/math/matrix_related/xor_basis_ordered.hpp b/library/math/matrix_related/xor_basis_ordered.hpp index 7cadd72d..a8ecb6ca 100644 --- a/library/math/matrix_related/xor_basis_ordered.hpp +++ b/library/math/matrix_related/xor_basis_ordered.hpp @@ -25,4 +25,14 @@ template struct basis_ordered { int i = shrink(v); return i >= 0 ? b[i] = v, ++siz : 0; } + T walk(T k) { + T res{}; + for (int i = lg - 1, j = siz - 1; i >= 0; i--) + if (b[i] != T(0)) { + if ((((res >> i) ^ (k >> j)) & T(1)) != T(0)) + res ^= b[i]; + j--; + } + return res; + } }; From 39a94dd1a96fa903dcb90f27c2b97c87c97f3d9b Mon Sep 17 00:00:00 2001 From: GitHub Date: Sat, 7 Mar 2026 00:38:36 +0000 Subject: [PATCH 02/10] [auto-verifier] verify commit 8c0af3f31f5e1ff76907270b324a4d4559be55df --- .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 c50e6702..f363cb62 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -106,7 +106,7 @@ "tests/library_checker_aizu_tests/math/solve_linear_mod.test.cpp": "2025-09-07 16:12:35 -0600", "tests/library_checker_aizu_tests/math/tetration.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/math/totient.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/math/xor_basis_intersection.test.cpp": "2026-03-06 16:39:24 -0700", +"tests/library_checker_aizu_tests/math/xor_basis_intersection.test.cpp": "2026-03-06 17:30:22 -0700", "tests/library_checker_aizu_tests/monotonic_stack_related/cartesian_binary_tree.test.cpp": "2025-02-10 14:50:36 -0700", "tests/library_checker_aizu_tests/monotonic_stack_related/cartesian_k_ary_tree.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/monotonic_stack_related/count_rectangles.test.cpp": "2026-01-18 11:15:41 +0000", From 796f68eaef9fa22a4bc70baefe7edcac8d0b9181 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sun, 8 Mar 2026 13:15:32 -0600 Subject: [PATCH 03/10] changes --- library/math/matrix_related/walk.hpp | 6 +++ .../math/matrix_related/xor_basis_ordered.hpp | 38 +++++++---------- .../handmade_tests/xor_basis_walk.test.cpp | 41 +++++++++++++++++++ 3 files changed, 61 insertions(+), 24 deletions(-) create mode 100644 library/math/matrix_related/walk.hpp create mode 100644 tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp diff --git a/library/math/matrix_related/walk.hpp b/library/math/matrix_related/walk.hpp new file mode 100644 index 00000000..a28bbf8e --- /dev/null +++ b/library/math/matrix_related/walk.hpp @@ -0,0 +1,6 @@ +bitset walk(bitset& k) { + bitset res; + for (int i = B, j = npivot; i--;) + if (basis[i][i] && res[i] ^ k[--j]) res ^= basis[i]; + return res; +} diff --git a/library/math/matrix_related/xor_basis_ordered.hpp b/library/math/matrix_related/xor_basis_ordered.hpp index a8ecb6ca..33da26ec 100644 --- a/library/math/matrix_related/xor_basis_ordered.hpp +++ b/library/math/matrix_related/xor_basis_ordered.hpp @@ -5,34 +5,24 @@ //! basis_ordered b1; //! basis_ordered b2; //! basis_ordered> b3; -//! b2.insert(x); // 0 <= x < (1LL< struct basis_ordered { - int siz = 0; - T b[lg]{}; - int shrink(T& v) { - for (int i = lg - 1; i >= 0; i--) - if (((v >> i) & T(1)) != T(0)) { - if (b[i] == T(0)) return i; - v ^= b[i]; +//! @time O(q * B^2/32) +//! @space O(B^2/32) +template struct xor_basis { + bitset basis[B]; + int npivot = 0, nfree = 0; + int shrink(bitset& v) { + for (int i = B; i--;) + if (v[i]) { + if (basis[i][i]) return i; + v ^= basis[i]; } return -1; } - bool insert(T v) { + bool insert(bitset& v) { int i = shrink(v); - return i >= 0 ? b[i] = v, ++siz : 0; - } - T walk(T k) { - T res{}; - for (int i = lg - 1, j = siz - 1; i >= 0; i--) - if (b[i] != T(0)) { - if ((((res >> i) ^ (k >> j)) & T(1)) != T(0)) - res ^= b[i]; - j--; - } - return res; + return i >= 0 ? basis[i] = v, ++npivot : !++nfree; } +#include "walk.hpp" }; diff --git a/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp new file mode 100644 index 00000000..452d78ef --- /dev/null +++ b/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp @@ -0,0 +1,41 @@ +#define PROBLEM \ + "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A" +#include "../template.hpp" +#include "../../../library/contest/random.hpp" +#include "../../../library/math/matrix_related/xor_basis_ordered.hpp" +const int B = 18; +vector> get_all(const vector>& basis) { + int n = ssize(basis); + vector> span; + for (int mask = 0; mask < (1 << n); mask++) { + bitset curr_xor; + assert(curr_xor.none()); + for (int bit = 0; bit < n; bit++) + if ((mask >> bit) & 1) curr_xor ^= basis[bit]; + span.push_back(curr_xor); + } + ranges::sort(span, {}, [&](const bitset& x) -> long { + return x.to_ulong(); + }); + return span; +} +int main() { + cin.tie(0)->sync_with_stdio(0); + for (int num_tests = 0; num_tests < 10000; num_tests++) { + xor_basis b; + int n = rnd(1, 18); + vector> naive_basis; + for (int i = 0; i < n; i++) { + bitset val = rnd(0, (1 << n) - 1); + if (b.insert(val)) naive_basis.push_back(val); + } + vector> fast_basis; + for (int i = 0; i < B; i++) + if (b.basis[i].any()) + fast_basis.push_back(b.basis[i]); + vector> naive_span = get_all(naive_basis); + vector> fast_span = get_all(fast_basis); + assert(naive_span == fast_span); + } + cout << "Hello World\n"; +} From 1e988d456036de63dac486d84f31d7d26997d628 Mon Sep 17 00:00:00 2001 From: GitHub Date: Sun, 8 Mar 2026 19:17:11 +0000 Subject: [PATCH 04/10] [auto-verifier] verify commit 796f68eaef9fa22a4bc70baefe7edcac8d0b9181 --- .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 f363cb62..138b21c3 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -90,6 +90,7 @@ "tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp": "2026-01-23 04:31:29 +0000", "tests/library_checker_aizu_tests/handmade_tests/seg_tree_find_small.test.cpp": "2026-01-23 04:31:29 +0000", "tests/library_checker_aizu_tests/handmade_tests/seg_tree_midpoint.test.cpp": "2026-02-27 11:16:07 -0700", +"tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp": "2026-03-08 13:15:32 -0600", "tests/library_checker_aizu_tests/loops/chooses.test.cpp": "2025-02-10 14:50:36 -0700", "tests/library_checker_aizu_tests/loops/quotients.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/loops/submasks.test.cpp": "2025-02-10 14:50:36 -0700", @@ -106,7 +107,6 @@ "tests/library_checker_aizu_tests/math/solve_linear_mod.test.cpp": "2025-09-07 16:12:35 -0600", "tests/library_checker_aizu_tests/math/tetration.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/math/totient.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/math/xor_basis_intersection.test.cpp": "2026-03-06 17:30:22 -0700", "tests/library_checker_aizu_tests/monotonic_stack_related/cartesian_binary_tree.test.cpp": "2025-02-10 14:50:36 -0700", "tests/library_checker_aizu_tests/monotonic_stack_related/cartesian_k_ary_tree.test.cpp": "2026-01-18 11:15:41 +0000", "tests/library_checker_aizu_tests/monotonic_stack_related/count_rectangles.test.cpp": "2026-01-18 11:15:41 +0000", From 4e9e30d6da3324a799dc2686096c1af73ea8b6b0 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sun, 8 Mar 2026 13:19:18 -0600 Subject: [PATCH 05/10] add assert to test it now --- library/math/matrix_related/walk.hpp | 2 +- .../handmade_tests/xor_basis_walk.test.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/library/math/matrix_related/walk.hpp b/library/math/matrix_related/walk.hpp index a28bbf8e..e8a59a7d 100644 --- a/library/math/matrix_related/walk.hpp +++ b/library/math/matrix_related/walk.hpp @@ -1,4 +1,4 @@ -bitset walk(bitset& k) { +bitset walk(const bitset& k) { bitset res; for (int i = B, j = npivot; i--;) if (basis[i][i] && res[i] ^ k[--j]) res ^= basis[i]; diff --git a/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp index 452d78ef..a2e4d6af 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp @@ -28,14 +28,16 @@ int main() { for (int i = 0; i < n; i++) { bitset val = rnd(0, (1 << n) - 1); if (b.insert(val)) naive_basis.push_back(val); + assert(b.npivot + b.nfree == i + 1); } vector> fast_basis; for (int i = 0; i < B; i++) - if (b.basis[i].any()) - fast_basis.push_back(b.basis[i]); + if (b.basis[i][i]) fast_basis.push_back(b.basis[i]); vector> naive_span = get_all(naive_basis); vector> fast_span = get_all(fast_basis); assert(naive_span == fast_span); + for (int i = 0; i < ssize(naive_span); i++) + assert(naive_span[i] == b.walk(i)); } cout << "Hello World\n"; } From 504ae7de67bb53121393446d2e36c2fd4a05a072 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sun, 8 Mar 2026 13:19:49 -0600 Subject: [PATCH 06/10] asdf --- .../handmade_tests/xor_basis_walk.test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp index a2e4d6af..8d73ea3d 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp @@ -30,6 +30,7 @@ int main() { if (b.insert(val)) naive_basis.push_back(val); assert(b.npivot + b.nfree == i + 1); } + assert(ssize(naive_basis) == b.npivot); vector> fast_basis; for (int i = 0; i < B; i++) if (b.basis[i][i]) fast_basis.push_back(b.basis[i]); From edff1eb85a722b8f1f0b62b6dce65ec055dc6f44 Mon Sep 17 00:00:00 2001 From: GitHub Date: Sun, 8 Mar 2026 19:21:24 +0000 Subject: [PATCH 07/10] [auto-verifier] verify commit 504ae7de67bb53121393446d2e36c2fd4a05a072 --- .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 138b21c3..4e850ec5 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -90,7 +90,7 @@ "tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp": "2026-01-23 04:31:29 +0000", "tests/library_checker_aizu_tests/handmade_tests/seg_tree_find_small.test.cpp": "2026-01-23 04:31:29 +0000", "tests/library_checker_aizu_tests/handmade_tests/seg_tree_midpoint.test.cpp": "2026-02-27 11:16:07 -0700", -"tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp": "2026-03-08 13:15:32 -0600", +"tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp": "2026-03-08 13:19:49 -0600", "tests/library_checker_aizu_tests/loops/chooses.test.cpp": "2025-02-10 14:50:36 -0700", "tests/library_checker_aizu_tests/loops/quotients.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/loops/submasks.test.cpp": "2025-02-10 14:50:36 -0700", From 9e2a6e496cc5de14501de0103a7aed364cf7dda7 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sun, 8 Mar 2026 13:35:39 -0600 Subject: [PATCH 08/10] fix test now --- library/math/matrix_related/walk.hpp | 2 +- .../math/matrix_related/xor_basis_ordered.hpp | 2 +- .../math/xor_basis_intersection.test.cpp | 65 ++++++++----------- 3 files changed, 29 insertions(+), 40 deletions(-) diff --git a/library/math/matrix_related/walk.hpp b/library/math/matrix_related/walk.hpp index e8a59a7d..a28bbf8e 100644 --- a/library/math/matrix_related/walk.hpp +++ b/library/math/matrix_related/walk.hpp @@ -1,4 +1,4 @@ -bitset walk(const bitset& k) { +bitset walk(bitset& k) { bitset res; for (int i = B, j = npivot; i--;) if (basis[i][i] && res[i] ^ k[--j]) res ^= basis[i]; diff --git a/library/math/matrix_related/xor_basis_ordered.hpp b/library/math/matrix_related/xor_basis_ordered.hpp index 33da26ec..b3c01848 100644 --- a/library/math/matrix_related/xor_basis_ordered.hpp +++ b/library/math/matrix_related/xor_basis_ordered.hpp @@ -15,7 +15,7 @@ template struct xor_basis { int shrink(bitset& v) { for (int i = B; i--;) if (v[i]) { - if (basis[i][i]) return i; + if (!basis[i][i]) return i; v ^= basis[i]; } return -1; diff --git a/tests/library_checker_aizu_tests/math/xor_basis_intersection.test.cpp b/tests/library_checker_aizu_tests/math/xor_basis_intersection.test.cpp index b898fd62..f4145d77 100644 --- a/tests/library_checker_aizu_tests/math/xor_basis_intersection.test.cpp +++ b/tests/library_checker_aizu_tests/math/xor_basis_intersection.test.cpp @@ -14,20 +14,16 @@ void check_condition_unordered(const basis& b) { or_bits |= b.b[i]; } } -void check_condition_ordered( - const basis_ordered& basis3, - const basis_ordered>& basis4) { - ll or_bits3 = 0; - bitset or_bits4 = 0; - for (int i = 0; i < lg; i++) { - assert(basis3.b[i] == 0 || - bit_floor(1ULL * basis3.b[i]) == (1ULL << i)); - assert( - (bit_floor(uint64_t(basis3.b[i])) & or_bits3) == 0); - assert((bit_floor(uint64_t(basis4.b[i].to_ullong())) & - or_bits4.to_ullong()) == 0); - or_bits3 |= basis3.b[i]; - or_bits4 |= basis4.b[i]; +const int B = 30; +void check_condition_ordered(const xor_basis& basis2) { + bitset or_bits2; + for (int i = 0; i < B; i++) { + assert(basis2.basis[i].none() || + bit_floor(basis2.basis[i].to_ulong()) == + (1ULL << i)); + assert((bit_floor(basis2.basis[i].to_ulong()) & + or_bits2.to_ulong()) == 0); + or_bits2 |= basis2.basis[i]; } } int main() { @@ -38,43 +34,36 @@ int main() { int n; cin >> n; basis basis1; - basis_ordered basis2; // to check that it compiles - assert( - sz(basis2.b) == lg); // remove unused var warning - basis_ordered basis3; - basis_ordered> basis4; + xor_basis basis2; + for (int i = 0; i < B; i++) + assert(basis2.basis[i].none()); for (int i = 0; i < n; i++) { int val; cin >> val; + bitset v = val; assert(basis1.insert(val)); assert(!basis1.insert(val)); - assert(basis3.insert(val)); - assert(!basis3.insert(val)); - assert(basis4.insert(val)); - assert(!basis4.insert(val)); + assert(basis2.insert(v)); + assert(!basis2.insert(v)); } check_condition_unordered(basis1); - check_condition_ordered(basis3, basis4); + check_condition_ordered(basis2); int m; cin >> m; - basis basis5; - basis_ordered basis6; - assert(sz(basis6.b) == lg); - basis_ordered basis7; - basis_ordered> basis8; + basis basis3; + xor_basis basis4; for (int j = 0; j < m; j++) { int val; cin >> val; - assert(basis5.insert(val)); - assert(!basis5.insert(val)); - assert(basis7.insert(val)); - assert(!basis7.insert(val)); - assert(basis8.insert(val)); - assert(!basis8.insert(val)); + bitset v = val; + assert(basis3.insert(val)); + assert(!basis3.insert(val)); + assert(basis4.insert(v)); + assert(!basis4.insert(v)); } - check_condition_unordered(basis5); - check_condition_ordered(basis7, basis8); - basis inter = intersection(basis1, basis5); + check_condition_unordered(basis3); + check_condition_ordered(basis4); + basis inter = intersection(basis1, basis3); check_condition_unordered(inter); cout << sz(inter.b) << " "; for (int val : inter.b) cout << val << " "; From f5c73401b0fd765bfee20c81e3ff21dfc14b13ac Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sun, 8 Mar 2026 13:37:25 -0600 Subject: [PATCH 09/10] fix test --- .../handmade_tests/xor_basis_walk.test.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp index 8d73ea3d..8c5ce1e1 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/xor_basis_walk.test.cpp @@ -21,7 +21,7 @@ vector> get_all(const vector>& basis) { } int main() { cin.tie(0)->sync_with_stdio(0); - for (int num_tests = 0; num_tests < 10000; num_tests++) { + for (int num_tests = 0; num_tests < 1000; num_tests++) { xor_basis b; int n = rnd(1, 18); vector> naive_basis; @@ -37,8 +37,10 @@ int main() { vector> naive_span = get_all(naive_basis); vector> fast_span = get_all(fast_basis); assert(naive_span == fast_span); - for (int i = 0; i < ssize(naive_span); i++) - assert(naive_span[i] == b.walk(i)); + for (int i = 0; i < ssize(naive_span); i++) { + bitset k = i; + assert(naive_span[i] == b.walk(k)); + } } cout << "Hello World\n"; } From f6414e509e8eaaa51f7eec7173cb2e104ca1ce87 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sun, 8 Mar 2026 13:39:22 -0600 Subject: [PATCH 10/10] fix --- tests/.config/.cppcheck_suppression_list | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/.config/.cppcheck_suppression_list b/tests/.config/.cppcheck_suppression_list index d6ad7f70..aa381399 100644 --- a/tests/.config/.cppcheck_suppression_list +++ b/tests/.config/.cppcheck_suppression_list @@ -63,4 +63,3 @@ unusedFunction:../kactl/stress-tests/utilities/genTree.h:49 containerOutOfBounds:../library/data_structures_[l,r)/uncommon/permutation_tree.hpp:85 ctuOneDefinitionRuleViolation:../library/data_structures_[l,r)/bit.hpp:5 ctuOneDefinitionRuleViolation:../library/data_structures_[l,r)/lazy_seg_tree.hpp:4 -shiftTooManyBits:../library/math/matrix_related/xor_basis_ordered.hpp:18