Skip to content

Commit 54ed8f1

Browse files
lrvideckisweb-flow
andauthored
Wavelet nit (#146)
* nit to wavelet matrix * [auto-verifier] verify commit adaa1d2 * update docs * [auto-verifier] verify commit 60ca7c0 * update docs for this * [auto-verifier] verify commit e79d2b8 * fix * fix * [auto-verifier] verify commit 5e31745 * minor golf --------- Co-authored-by: GitHub <noreply@github.com>
1 parent 0bb7ffc commit 54ed8f1

File tree

4 files changed

+28
-27
lines changed

4 files changed

+28
-27
lines changed

.verify-helper/timestamps.remote.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"tests/library_checker_aizu_tests/data_structures/implicit_seg_tree.test.cpp": "2024-11-17 14:04:03 -0600",
2525
"tests/library_checker_aizu_tests/data_structures/kruskal_tree_aizu.test.cpp": "2025-02-10 23:30:47 -0700",
2626
"tests/library_checker_aizu_tests/data_structures/kth_smallest_pst.test.cpp": "2024-12-05 10:41:42 -0600",
27-
"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2024-11-19 08:31:51 -0600",
27+
"tests/library_checker_aizu_tests/data_structures/kth_smallest_wavelet_matrix.test.cpp": "2025-07-10 11:33:52 -0600",
2828
"tests/library_checker_aizu_tests/data_structures/lazy_segment_tree.test.cpp": "2024-12-14 19:50:29 -0600",
2929
"tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_constructor.test.cpp": "2024-12-14 19:50:29 -0600",
3030
"tests/library_checker_aizu_tests/data_structures/lazy_segment_tree_inc.test.cpp": "2024-12-05 10:41:42 -0600",
@@ -74,7 +74,7 @@
7474
"tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2025-07-08 19:28:25 -0600",
7575
"tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2025-02-10 23:30:47 -0700",
7676
"tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-12-14 19:50:29 -0600",
77-
"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-02-11 13:53:30 -0700",
77+
"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-07-10 11:33:52 -0600",
7878
"tests/library_checker_aizu_tests/handmade_tests/mobius.test.cpp": "2025-02-10 14:50:36 -0700",
7979
"tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp": "2024-12-14 19:50:29 -0600",
8080
"tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp": "2025-01-15 00:22:31 -0700",
Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
#pragma once
2-
#define ull uint64_t
2+
//! @code
3+
//! vector<bool> a(n);
4+
//! bit_vec bv(a);
5+
//! bv.cnt(r); // a[0] + a[1] + ... + a[r - 1]
6+
//! @endcode
7+
//! @time O(n + q)
8+
//! @space O(n / 64)
9+
using ull = uint64_t;
310
struct bit_vec {
411
vector<pair<ull, int>> b;
5-
//! @time O(n)
6-
//! @space O(n / 64)
712
bit_vec(const vector<bool>& a): b(sz(a) / 64 + 1) {
813
rep(i, 0, sz(a)) b[i >> 6].first |= ull(a[i])
914
<< (i & 63);
1015
rep(i, 0, sz(b) - 1) b[i + 1].second =
1116
popcount(b[i].first) + b[i].second;
1217
}
13-
//! @returns !a[0] + !a[1] + ... + !a[r - 1]
14-
//! @time O(1)
15-
//! @space O(1)
16-
int cnt0(int r) {
18+
int cnt(int r) {
1719
auto [x, y] = b[r >> 6];
18-
return r - y - popcount(x & ((1ULL << (r & 63)) - 1));
20+
return y + popcount(x & ((1ULL << (r & 63)) - 1));
1921
}
2022
};

library/data_structures/seg_tree_uncommon/wavelet_count_less.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
int count(int l, int r, ull ub) {
66
int res = 0;
77
for (int h = sz(bv); h--;) {
8-
int l0 = bv[h].cnt0(l), r0 = bv[h].cnt0(r);
8+
int l0 = bv[h].cnt(l), r0 = bv[h].cnt(r);
99
if ((~ub >> h) & 1) l = l0, r = r0;
1010
else
11-
res += r0 - l0, l += bv[h].cnt0(n) - l0,
12-
r += bv[h].cnt0(n) - r0;
11+
res += r0 - l0, l += bv[h].cnt(n) - l0,
12+
r += bv[h].cnt(n) - r0;
1313
}
1414
return res;
1515
}

library/data_structures/seg_tree_uncommon/wavelet_matrix.hpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
11
#pragma once
2+
//! @code
3+
//! vector<ull> a(n);
4+
//! wavelet_matrix wm(a, 1e9); // requires a[i] <= 1e9
5+
//! wm.kth(l, r, k); //(k+1)th smallest number in [l,r)
6+
//! wm.kth(l, r, 0); //min in [l,r)
7+
//! @endcode
8+
//! @time O(n * log(max_val) + q * log(max_val))
9+
//! @space O(n * log(max_val) / 64)
210
#include "wavelet_bit_vec.hpp"
311
struct wavelet_matrix {
412
int n;
513
vector<bit_vec> bv;
6-
//! Requires a[i] <= max_val
7-
//! @time O(n * log(max_val))
8-
//! @space O(n * log(max_val) / 64)
914
wavelet_matrix(vector<ull> a, ull max_val):
1015
n(sz(a)), bv(bit_width(max_val), {{}}) {
11-
vector<ull> nxt(n);
1216
for (int h = sz(bv); h--;) {
17+
int i = 0;
1318
vector<bool> b(n);
14-
rep(i, 0, n) b[i] = (a[i] >> h) & 1;
19+
ranges::stable_partition(a,
20+
[&](ull x) { return b[i++] = (~x >> h) & 1; });
1521
bv[h] = b;
16-
array it{begin(nxt), begin(nxt) + bv[h].cnt0(n)};
17-
rep(i, 0, n) * it[b[i]]++ = a[i];
18-
swap(a, nxt);
1922
}
2023
}
21-
//! (k+1)th smallest number in [l,r)
22-
//! kth(l,r,0) returns the min
23-
//! @time O(log(max_val))
24-
//! @space O(1)
2524
ull kth(int l, int r, int k) {
2625
ll res = 0;
2726
for (int h = sz(bv); h--;) {
28-
int l0 = bv[h].cnt0(l), r0 = bv[h].cnt0(r);
27+
int l0 = bv[h].cnt(l), r0 = bv[h].cnt(r);
2928
if (k < r0 - l0) l = l0, r = r0;
3029
else
3130
k -= r0 - l0, res |= 1ULL << h,
32-
l += bv[h].cnt0(n) - l0, r += bv[h].cnt0(n) - r0;
31+
l += bv[h].cnt(n) - l0, r += bv[h].cnt(n) - r0;
3332
}
3433
return res;
3534
}

0 commit comments

Comments
 (0)