diff --git a/library/data_structures_[l,r)/bit.hpp b/library/data_structures_[l,r)/bit.hpp index 4b6cc0be..0ee5f36c 100644 --- a/library/data_structures_[l,r)/bit.hpp +++ b/library/data_structures_[l,r)/bit.hpp @@ -1,4 +1,13 @@ #pragma once +//! @code +//! BIT bit(n); +//! bit.walk([&](int r, ll sum) -> bool { +//! // sum = a[0] + a[1] + ... + a[r - 1] +//! }); +//! int r = bit.walk2(sum); +//! // Returns min r s.t. sum of [0,r] >= sum +//! // Returns n if sum of [0,n-1] < sum +//! @endcode //! @time O(n + q log n) //! @space O(n) // NOLINTNEXTLINE(readability-identifier-naming) diff --git a/library/data_structures_[l,r)/bit_uncommon/walk.hpp b/library/data_structures_[l,r)/bit_uncommon/walk.hpp index 85d984d1..20c3a732 100644 --- a/library/data_structures_[l,r)/bit_uncommon/walk.hpp +++ b/library/data_structures_[l,r)/bit_uncommon/walk.hpp @@ -1,6 +1,3 @@ -//! Requires sum of [i,i] >= 0 -//! Returns min r s.t. sum of [0,r] >= sum -//! Returns n if sum of [0,n-1] < sum int walk2(ll sum) { if (sum <= 0) return -1; int r = 0; diff --git a/library/data_structures_[l,r]/bit.hpp b/library/data_structures_[l,r]/bit.hpp index 72a77a7c..ba96de89 100644 --- a/library/data_structures_[l,r]/bit.hpp +++ b/library/data_structures_[l,r]/bit.hpp @@ -1,4 +1,13 @@ #pragma once +//! @code +//! BIT bit(n); +//! bit.walk([&](int r, ll sum) -> bool { +//! // sum = a[0] + a[1] + ... + a[r] +//! }); +//! int r = bit.walk2(sum); +//! // Returns min r s.t. sum of [0,r] >= sum +//! // Returns n if sum of [0,n-1] < sum +//! @endcode //! @time O(n + q log n) //! @space O(n) // NOLINTNEXTLINE(readability-identifier-naming) @@ -17,5 +26,6 @@ struct BIT { ll query(int l, int r) { return query(r) - query(l - 1); } +#include "bit_uncommon/walk_lambda.hpp" #include "../data_structures_[l,r)/bit_uncommon/walk.hpp" }; diff --git a/library/data_structures_[l,r]/bit_uncommon/walk_lambda.hpp b/library/data_structures_[l,r]/bit_uncommon/walk_lambda.hpp new file mode 100644 index 00000000..a87ee4af --- /dev/null +++ b/library/data_structures_[l,r]/bit_uncommon/walk_lambda.hpp @@ -0,0 +1,6 @@ +void walk(const auto& f) { + ll sum = 0; + for (int i = bit_floor(size(s)), r = 0; i; i /= 2) + if (r + i <= sz(s) && f(r + i - 1, sum + s[r + i - 1])) + sum += s[(r += i) - 1]; +} diff --git a/tests/.config/.code_snippet_excluded_file_list b/tests/.config/.code_snippet_excluded_file_list index f6dd52d1..6680d0b6 100644 --- a/tests/.config/.code_snippet_excluded_file_list +++ b/tests/.config/.code_snippet_excluded_file_list @@ -18,6 +18,7 @@ find_substrings_concatenated.hpp pascals_identity.hpp binary_search.hpp walk.hpp +walk_lambda.hpp prev.hpp next.hpp wavelet_count_less.hpp diff --git a/tests/.config/.cppcheck_suppression_list b/tests/.config/.cppcheck_suppression_list index aa381399..79794aaa 100644 --- a/tests/.config/.cppcheck_suppression_list +++ b/tests/.config/.cppcheck_suppression_list @@ -61,5 +61,5 @@ unusedFunction:../kactl/content/data-structures/UnionFind.h:14 unusedFunction:../kactl/content/number-theory/ModPow.h:13 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)/bit.hpp:14 ctuOneDefinitionRuleViolation:../library/data_structures_[l,r)/lazy_seg_tree.hpp:4 diff --git a/tests/library_checker_aizu_tests/data_structures/bit.test.cpp b/tests/library_checker_aizu_tests/data_structures/bit.test.cpp index f0353e12..3f80ba46 100644 --- a/tests/library_checker_aizu_tests/data_structures/bit.test.cpp +++ b/tests/library_checker_aizu_tests/data_structures/bit.test.cpp @@ -58,7 +58,7 @@ int main() { } return 1; }; - assert(bit.walk(sum) == st.find_first(0, n, f)); + assert(bit.walk2(sum) == st.find_first(0, n, f)); } return 0; } diff --git a/tests/library_checker_aizu_tests/data_structures/bit_inc_walk.test.cpp b/tests/library_checker_aizu_tests/data_structures/bit_inc_walk.test.cpp new file mode 100644 index 00000000..f9d5cf87 --- /dev/null +++ b/tests/library_checker_aizu_tests/data_structures/bit_inc_walk.test.cpp @@ -0,0 +1,51 @@ +#define PROBLEM \ + "https://judge.yosupo.jp/problem/predecessor_problem" +#include "../template.hpp" +#include "../../../library/data_structures_[l,r]/bit.hpp" +int main() { + cin.tie(0)->sync_with_stdio(0); + int n, q; + string s; + cin >> n >> q >> s; + vector init(n); + for (int i = 0; i < n; i++) init[i] = s[i] - '0'; + BIT bit(init); + while (q--) { + int type, k; + cin >> type >> k; + if (type == 0) { + if (bit.query(k, k) == 0) bit.update(k, 1); + } else if (type == 1) { + if (bit.query(k, k) == 1) bit.update(k, -1); + } else if (type == 2) { + cout << bit.query(k, k) << '\n'; + } else if (type == 3) { + if (bit.query(k, n - 1) == 0) cout << -1 << '\n'; + else { + ll order = bit.query(k - 1); + int res = -1; + bit.walk([&](int r, ll sum) { + if (sum <= order) return 1; + res = r; + return 0; + }); + cout << res << '\n'; + } + } else { + if (bit.query(k) == 0) cout << -1 << '\n'; + else { + ll order = bit.query(k); + int res = -1; + bit.walk([&](int r, ll sum) { + if (sum >= order) { + res = r; + return 0; + } + return 1; + }); + cout << res << '\n'; + } + } + } + return 0; +} diff --git a/tests/library_checker_aizu_tests/data_structures/bit_ordered_set.test.cpp b/tests/library_checker_aizu_tests/data_structures/bit_ordered_set.test.cpp index 3349d015..aeef3a5c 100644 --- a/tests/library_checker_aizu_tests/data_structures/bit_ordered_set.test.cpp +++ b/tests/library_checker_aizu_tests/data_structures/bit_ordered_set.test.cpp @@ -40,7 +40,7 @@ int main() { x = get_compressed_idx(x); if (bit.query(x, x) == 1) bit.update(x, -1); } else if (type == 2) { - int res = bit.walk(x); + int res = bit.walk2(x); if (res == -1 || res == ssize(compress)) cout << -1 << '\n'; else cout << compress[res] << '\n'; @@ -49,12 +49,12 @@ int main() { cout << bit.query(x) << '\n'; } else if (type == 4) { x = get_compressed_idx(x); - int res = bit.walk(bit.query(x)); + int res = bit.walk2(bit.query(x)); if (res == -1) cout << -1 << '\n'; else cout << compress[res] << '\n'; } else { x = get_compressed_idx(x); - int res = bit.walk(bit.query(x - 1) + 1); + int res = bit.walk2(bit.query(x - 1) + 1); if (res == ssize(bit.s)) cout << -1 << '\n'; else cout << compress[res] << '\n'; } diff --git a/tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp index 42248b64..9efea020 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp @@ -38,7 +38,7 @@ int main() { rngs.push_back({tl, tr, 1}); return 1; }; - int pos = min(bit.walk(bit.query(l) + sum), r); + int pos = min(bit.walk2(bit.query(l) + sum), r); reset(); assert(pos == seg.find_first(l, r, f)); assert(!empty(rngs)); diff --git a/tests/scripts/compile_commented_snippets.sh b/tests/scripts/compile_commented_snippets.sh index 4d73abfc..785ace98 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,w,lsz,rsz,cols,cap,num,x,y,i,j,i1,i2,j1,j2,len;" + 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,w,lsz,rsz,cols,cap,num,x,y,i,j,i1,i2,j1,j2,len,sum;" } >entire_library_without_main {