Skip to content

Commit 20da0a9

Browse files
authored
Bit walk (#200)
* add walk for [l,r] now * fix * update docs now * fix build * update docs again * fix build * fix * yet another fix lol * fix * sdaoivnsdfoiasndvoiasndvoinaes FIX
1 parent 773ef24 commit 20da0a9

File tree

11 files changed

+84
-10
lines changed

11 files changed

+84
-10
lines changed

library/data_structures_[l,r)/bit.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
#pragma once
2+
//! @code
3+
//! BIT bit(n);
4+
//! bit.walk([&](int r, ll sum) -> bool {
5+
//! // sum = a[0] + a[1] + ... + a[r - 1]
6+
//! });
7+
//! int r = bit.walk2(sum);
8+
//! // Returns min r s.t. sum of [0,r] >= sum
9+
//! // Returns n if sum of [0,n-1] < sum
10+
//! @endcode
211
//! @time O(n + q log n)
312
//! @space O(n)
413
// NOLINTNEXTLINE(readability-identifier-naming)

library/data_structures_[l,r)/bit_uncommon/walk.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
//! Requires sum of [i,i] >= 0
2-
//! Returns min r s.t. sum of [0,r] >= sum
3-
//! Returns n if sum of [0,n-1] < sum
41
int walk2(ll sum) {
52
if (sum <= 0) return -1;
63
int r = 0;

library/data_structures_[l,r]/bit.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
#pragma once
2+
//! @code
3+
//! BIT bit(n);
4+
//! bit.walk([&](int r, ll sum) -> bool {
5+
//! // sum = a[0] + a[1] + ... + a[r]
6+
//! });
7+
//! int r = bit.walk2(sum);
8+
//! // Returns min r s.t. sum of [0,r] >= sum
9+
//! // Returns n if sum of [0,n-1] < sum
10+
//! @endcode
211
//! @time O(n + q log n)
312
//! @space O(n)
413
// NOLINTNEXTLINE(readability-identifier-naming)
@@ -17,5 +26,6 @@ struct BIT {
1726
ll query(int l, int r) {
1827
return query(r) - query(l - 1);
1928
}
29+
#include "bit_uncommon/walk_lambda.hpp"
2030
#include "../data_structures_[l,r)/bit_uncommon/walk.hpp"
2131
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
void walk(const auto& f) {
2+
ll sum = 0;
3+
for (int i = bit_floor(size(s)), r = 0; i; i /= 2)
4+
if (r + i <= sz(s) && f(r + i - 1, sum + s[r + i - 1]))
5+
sum += s[(r += i) - 1];
6+
}

tests/.config/.code_snippet_excluded_file_list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ find_substrings_concatenated.hpp
1818
pascals_identity.hpp
1919
binary_search.hpp
2020
walk.hpp
21+
walk_lambda.hpp
2122
prev.hpp
2223
next.hpp
2324
wavelet_count_less.hpp

tests/.config/.cppcheck_suppression_list

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,5 @@ unusedFunction:../kactl/content/data-structures/UnionFind.h:14
6161
unusedFunction:../kactl/content/number-theory/ModPow.h:13
6262
unusedFunction:../kactl/stress-tests/utilities/genTree.h:49
6363
containerOutOfBounds:../library/data_structures_[l,r)/uncommon/permutation_tree.hpp:85
64-
ctuOneDefinitionRuleViolation:../library/data_structures_[l,r)/bit.hpp:5
64+
ctuOneDefinitionRuleViolation:../library/data_structures_[l,r)/bit.hpp:14
6565
ctuOneDefinitionRuleViolation:../library/data_structures_[l,r)/lazy_seg_tree.hpp:4

tests/library_checker_aizu_tests/data_structures/bit.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ int main() {
5858
}
5959
return 1;
6060
};
61-
assert(bit.walk(sum) == st.find_first(0, n, f));
61+
assert(bit.walk2(sum) == st.find_first(0, n, f));
6262
}
6363
return 0;
6464
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#define PROBLEM \
2+
"https://judge.yosupo.jp/problem/predecessor_problem"
3+
#include "../template.hpp"
4+
#include "../../../library/data_structures_[l,r]/bit.hpp"
5+
int main() {
6+
cin.tie(0)->sync_with_stdio(0);
7+
int n, q;
8+
string s;
9+
cin >> n >> q >> s;
10+
vector<ll> init(n);
11+
for (int i = 0; i < n; i++) init[i] = s[i] - '0';
12+
BIT bit(init);
13+
while (q--) {
14+
int type, k;
15+
cin >> type >> k;
16+
if (type == 0) {
17+
if (bit.query(k, k) == 0) bit.update(k, 1);
18+
} else if (type == 1) {
19+
if (bit.query(k, k) == 1) bit.update(k, -1);
20+
} else if (type == 2) {
21+
cout << bit.query(k, k) << '\n';
22+
} else if (type == 3) {
23+
if (bit.query(k, n - 1) == 0) cout << -1 << '\n';
24+
else {
25+
ll order = bit.query(k - 1);
26+
int res = -1;
27+
bit.walk([&](int r, ll sum) {
28+
if (sum <= order) return 1;
29+
res = r;
30+
return 0;
31+
});
32+
cout << res << '\n';
33+
}
34+
} else {
35+
if (bit.query(k) == 0) cout << -1 << '\n';
36+
else {
37+
ll order = bit.query(k);
38+
int res = -1;
39+
bit.walk([&](int r, ll sum) {
40+
if (sum >= order) {
41+
res = r;
42+
return 0;
43+
}
44+
return 1;
45+
});
46+
cout << res << '\n';
47+
}
48+
}
49+
}
50+
return 0;
51+
}

tests/library_checker_aizu_tests/data_structures/bit_ordered_set.test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ int main() {
4040
x = get_compressed_idx(x);
4141
if (bit.query(x, x) == 1) bit.update(x, -1);
4242
} else if (type == 2) {
43-
int res = bit.walk(x);
43+
int res = bit.walk2(x);
4444
if (res == -1 || res == ssize(compress))
4545
cout << -1 << '\n';
4646
else cout << compress[res] << '\n';
@@ -49,12 +49,12 @@ int main() {
4949
cout << bit.query(x) << '\n';
5050
} else if (type == 4) {
5151
x = get_compressed_idx(x);
52-
int res = bit.walk(bit.query(x));
52+
int res = bit.walk2(bit.query(x));
5353
if (res == -1) cout << -1 << '\n';
5454
else cout << compress[res] << '\n';
5555
} else {
5656
x = get_compressed_idx(x);
57-
int res = bit.walk(bit.query(x - 1) + 1);
57+
int res = bit.walk2(bit.query(x - 1) + 1);
5858
if (res == ssize(bit.s)) cout << -1 << '\n';
5959
else cout << compress[res] << '\n';
6060
}

tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int main() {
3838
rngs.push_back({tl, tr, 1});
3939
return 1;
4040
};
41-
int pos = min(bit.walk(bit.query(l) + sum), r);
41+
int pos = min(bit.walk2(bit.query(l) + sum), r);
4242
reset();
4343
assert(pos == seg.find_first(l, r, f));
4444
assert(!empty(rngs));

0 commit comments

Comments
 (0)