From adaa1d2de83572702fde6834cce6d5bd64966de6 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 10 Jul 2025 11:09:49 -0600 Subject: [PATCH 01/10] nit to wavelet matrix --- .../seg_tree_uncommon/wavelet_bit_vec.hpp | 6 +++--- .../seg_tree_uncommon/wavelet_count_less.hpp | 6 +++--- .../seg_tree_uncommon/wavelet_matrix.hpp | 12 +++++------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp b/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp index 9239e84d..8ea2a8d9 100644 --- a/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp +++ b/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp @@ -10,11 +10,11 @@ struct bit_vec { rep(i, 0, sz(b) - 1) b[i + 1].second = popcount(b[i].first) + b[i].second; } - //! @returns !a[0] + !a[1] + ... + !a[r - 1] + //! @returns a[0] + a[1] + ... + a[r - 1] //! @time O(1) //! @space O(1) - int cnt0(int r) { + int cnt(int r) { auto [x, y] = b[r >> 6]; - return r - y - popcount(x & ((1ULL << (r & 63)) - 1)); + return y + popcount(x & ((1ULL << (r & 63)) - 1)); } }; diff --git a/library/data_structures/seg_tree_uncommon/wavelet_count_less.hpp b/library/data_structures/seg_tree_uncommon/wavelet_count_less.hpp index 44e82615..2416ad02 100644 --- a/library/data_structures/seg_tree_uncommon/wavelet_count_less.hpp +++ b/library/data_structures/seg_tree_uncommon/wavelet_count_less.hpp @@ -5,11 +5,11 @@ int count(int l, int r, ull ub) { int res = 0; for (int h = sz(bv); h--;) { - int l0 = bv[h].cnt0(l), r0 = bv[h].cnt0(r); + int l0 = bv[h].cnt(l), r0 = bv[h].cnt(r); if ((~ub >> h) & 1) l = l0, r = r0; else - res += r0 - l0, l += bv[h].cnt0(n) - l0, - r += bv[h].cnt0(n) - r0; + res += r0 - l0, l += bv[h].cnt(n) - l0, + r += bv[h].cnt(n) - r0; } return res; } diff --git a/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp b/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp index bd4576c9..4ec42e31 100644 --- a/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp +++ b/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp @@ -8,14 +8,12 @@ struct wavelet_matrix { //! @space O(n * log(max_val) / 64) wavelet_matrix(vector a, ull max_val): n(sz(a)), bv(bit_width(max_val), {{}}) { - vector nxt(n); for (int h = sz(bv); h--;) { + int i = 0; vector b(n); - rep(i, 0, n) b[i] = (a[i] >> h) & 1; + ranges::stable_partition(a, + [&](ull x) { return b[i++] = !((x >> h) & 1); }); bv[h] = b; - array it{begin(nxt), begin(nxt) + bv[h].cnt0(n)}; - rep(i, 0, n) * it[b[i]]++ = a[i]; - swap(a, nxt); } } //! (k+1)th smallest number in [l,r) @@ -25,11 +23,11 @@ struct wavelet_matrix { ull kth(int l, int r, int k) { ll res = 0; for (int h = sz(bv); h--;) { - int l0 = bv[h].cnt0(l), r0 = bv[h].cnt0(r); + int l0 = bv[h].cnt(l), r0 = bv[h].cnt(r); if (k < r0 - l0) l = l0, r = r0; else k -= r0 - l0, res |= 1ULL << h, - l += bv[h].cnt0(n) - l0, r += bv[h].cnt0(n) - r0; + l += bv[h].cnt(n) - l0, r += bv[h].cnt(n) - r0; } return res; } From a36cce2536f06951567b943a438ee34ea61ccca7 Mon Sep 17 00:00:00 2001 From: GitHub Date: Thu, 10 Jul 2025 17:11:56 +0000 Subject: [PATCH 02/10] [auto-verifier] verify commit adaa1d2de83572702fde6834cce6d5bd64966de6 --- .verify-helper/timestamps.remote.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index e1823aed..ac487639 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -24,7 +24,7 @@ "tests/library_checker_aizu_tests/data_structures/implicit_seg_tree.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/data_structures/kruskal_tree_aizu.test.cpp": "2025-02-10 23:30:47 -0700", "tests/library_checker_aizu_tests/data_structures/kth_smallest_pst.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2024-11-19 08:31:51 -0600", +"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2025-07-10 11:09:49 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_constructor.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_inc.test.cpp": "2024-12-05 10:41:42 -0600", @@ -74,7 +74,7 @@ "tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2025-07-08 19:28:25 -0600", "tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2025-02-10 23:30:47 -0700", "tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-12-14 19:50:29 -0600", -"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-02-11 13:53:30 -0700", +"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-07-10 11:09:49 -0600", "tests/library_checker_aizu_tests/handmade_tests/mobius.test.cpp": "2025-02-10 14:50:36 -0700", "tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp": "2025-01-15 00:22:31 -0700", From 60ca7c0177a8d7147a637d120c83527d3b16efb7 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 10 Jul 2025 11:25:15 -0600 Subject: [PATCH 03/10] update docs --- .../seg_tree_uncommon/wavelet_matrix.hpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp b/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp index 4ec42e31..728ee544 100644 --- a/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp +++ b/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp @@ -1,11 +1,16 @@ #pragma once +//! @code +//! vector a(n); +//! wavelet_matrix wm(a, 1e9 /*a[i] <= 1e9*/); +//! wm.kth(l, r, k); //(k+1)th smallest number in [l,r) +//! wm.kth(l, r, 0); //min in [l,r) +//! @endcode +//! @time O(n * log(max_val) + q * log(max_val)) +//! @space O(n * log(max_val) / 64) #include "wavelet_bit_vec.hpp" struct wavelet_matrix { int n; vector bv; - //! Requires a[i] <= max_val - //! @time O(n * log(max_val)) - //! @space O(n * log(max_val) / 64) wavelet_matrix(vector a, ull max_val): n(sz(a)), bv(bit_width(max_val), {{}}) { for (int h = sz(bv); h--;) { @@ -16,10 +21,6 @@ struct wavelet_matrix { bv[h] = b; } } - //! (k+1)th smallest number in [l,r) - //! kth(l,r,0) returns the min - //! @time O(log(max_val)) - //! @space O(1) ull kth(int l, int r, int k) { ll res = 0; for (int h = sz(bv); h--;) { From 9095a85cd6f9ebeb39ec409a7ba5dcba6922e065 Mon Sep 17 00:00:00 2001 From: GitHub Date: Thu, 10 Jul 2025 17:27:17 +0000 Subject: [PATCH 04/10] [auto-verifier] verify commit 60ca7c0177a8d7147a637d120c83527d3b16efb7 --- .verify-helper/timestamps.remote.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index ac487639..4e50f371 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -24,7 +24,7 @@ "tests/library_checker_aizu_tests/data_structures/implicit_seg_tree.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/data_structures/kruskal_tree_aizu.test.cpp": "2025-02-10 23:30:47 -0700", "tests/library_checker_aizu_tests/data_structures/kth_smallest_pst.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2025-07-10 11:09:49 -0600", +"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2025-07-10 11:25:15 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_constructor.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_inc.test.cpp": "2024-12-05 10:41:42 -0600", @@ -74,7 +74,7 @@ "tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2025-07-08 19:28:25 -0600", "tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2025-02-10 23:30:47 -0700", "tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-12-14 19:50:29 -0600", -"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-07-10 11:09:49 -0600", +"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-07-10 11:25:15 -0600", "tests/library_checker_aizu_tests/handmade_tests/mobius.test.cpp": "2025-02-10 14:50:36 -0700", "tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp": "2025-01-15 00:22:31 -0700", From e79d2b8969610d74cdafaf1abc742281c69eb750 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 10 Jul 2025 11:29:14 -0600 Subject: [PATCH 05/10] update docs for this --- .../seg_tree_uncommon/wavelet_bit_vec.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp b/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp index 8ea2a8d9..649be928 100644 --- a/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp +++ b/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp @@ -1,18 +1,20 @@ #pragma once +//! @code +//! vector a(n); +//! bit_vec bv(a); +//! bv.cnt(r); // a[0] + a[1] + ... + a[r - 1] +//! @endcode +//! @time O(n + q) +//! @space O(n / 64) #define ull uint64_t struct bit_vec { vector> b; - //! @time O(n) - //! @space O(n / 64) bit_vec(const vector& a): b(sz(a) / 64 + 1) { rep(i, 0, sz(a)) b[i >> 6].first |= ull(a[i]) << (i & 63); rep(i, 0, sz(b) - 1) b[i + 1].second = popcount(b[i].first) + b[i].second; } - //! @returns a[0] + a[1] + ... + a[r - 1] - //! @time O(1) - //! @space O(1) int cnt(int r) { auto [x, y] = b[r >> 6]; return y + popcount(x & ((1ULL << (r & 63)) - 1)); From 3225f237c4e4c06fce9176207008b88bd7360aab Mon Sep 17 00:00:00 2001 From: GitHub Date: Thu, 10 Jul 2025 17:31:23 +0000 Subject: [PATCH 06/10] [auto-verifier] verify commit e79d2b8969610d74cdafaf1abc742281c69eb750 --- .verify-helper/timestamps.remote.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 4e50f371..95139602 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -24,7 +24,7 @@ "tests/library_checker_aizu_tests/data_structures/implicit_seg_tree.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/data_structures/kruskal_tree_aizu.test.cpp": "2025-02-10 23:30:47 -0700", "tests/library_checker_aizu_tests/data_structures/kth_smallest_pst.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2025-07-10 11:25:15 -0600", +"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2025-07-10 11:29:14 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_constructor.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_inc.test.cpp": "2024-12-05 10:41:42 -0600", @@ -74,7 +74,7 @@ "tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2025-07-08 19:28:25 -0600", "tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2025-02-10 23:30:47 -0700", "tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-12-14 19:50:29 -0600", -"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-07-10 11:25:15 -0600", +"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-07-10 11:29:14 -0600", "tests/library_checker_aizu_tests/handmade_tests/mobius.test.cpp": "2025-02-10 14:50:36 -0700", "tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp": "2025-01-15 00:22:31 -0700", From fbe465b3bb0afa650043eae6cc82a1b665178b0b Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 10 Jul 2025 11:32:45 -0600 Subject: [PATCH 07/10] fix --- library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp b/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp index 728ee544..4e887b5e 100644 --- a/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp +++ b/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp @@ -1,7 +1,7 @@ #pragma once //! @code //! vector a(n); -//! wavelet_matrix wm(a, 1e9 /*a[i] <= 1e9*/); +//! wavelet_matrix wm(a, 1e9); // requires a[i] <= 1e9 //! wm.kth(l, r, k); //(k+1)th smallest number in [l,r) //! wm.kth(l, r, 0); //min in [l,r) //! @endcode From 5e317459902d24e4798d6aa3cd3f3f79640a022c Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 10 Jul 2025 11:33:52 -0600 Subject: [PATCH 08/10] fix --- library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp b/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp index 649be928..aecb75e6 100644 --- a/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp +++ b/library/data_structures/seg_tree_uncommon/wavelet_bit_vec.hpp @@ -6,7 +6,7 @@ //! @endcode //! @time O(n + q) //! @space O(n / 64) -#define ull uint64_t +using ull = uint64_t; struct bit_vec { vector> b; bit_vec(const vector& a): b(sz(a) / 64 + 1) { From c917157aee60885f60c5a5de0c28832269b008a2 Mon Sep 17 00:00:00 2001 From: GitHub Date: Thu, 10 Jul 2025 17:35:58 +0000 Subject: [PATCH 09/10] [auto-verifier] verify commit 5e317459902d24e4798d6aa3cd3f3f79640a022c --- .verify-helper/timestamps.remote.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 95139602..11a4ba80 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -24,7 +24,7 @@ "tests/library_checker_aizu_tests/data_structures/implicit_seg_tree.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/data_structures/kruskal_tree_aizu.test.cpp": "2025-02-10 23:30:47 -0700", "tests/library_checker_aizu_tests/data_structures/kth_smallest_pst.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2025-07-10 11:29:14 -0600", +"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2025-07-10 11:33:52 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_constructor.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_inc.test.cpp": "2024-12-05 10:41:42 -0600", @@ -74,7 +74,7 @@ "tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2025-07-08 19:28:25 -0600", "tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2025-02-10 23:30:47 -0700", "tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-12-14 19:50:29 -0600", -"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-07-10 11:29:14 -0600", +"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-07-10 11:33:52 -0600", "tests/library_checker_aizu_tests/handmade_tests/mobius.test.cpp": "2025-02-10 14:50:36 -0700", "tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp": "2025-01-15 00:22:31 -0700", From 5ba1cec9b256a2edfbb2efba77232e8df457e674 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Thu, 10 Jul 2025 11:40:46 -0600 Subject: [PATCH 10/10] minor golf --- library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp b/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp index 4e887b5e..cf499054 100644 --- a/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp +++ b/library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp @@ -17,7 +17,7 @@ struct wavelet_matrix { int i = 0; vector b(n); ranges::stable_partition(a, - [&](ull x) { return b[i++] = !((x >> h) & 1); }); + [&](ull x) { return b[i++] = (~x >> h) & 1; }); bv[h] = b; } }