Skip to content

Commit f48d56e

Browse files
lrvideckisweb-flow
andauthored
update interface of ST walk to be more useful (#194)
* update interface of ST walk to be more useful * [auto-verifier] verify commit 772aa5c * fix * [auto-verifier] verify commit 01a21fe * now inc-exc changes --------- Co-authored-by: GitHub <noreply@github.com>
1 parent eeb718c commit f48d56e

File tree

11 files changed

+103
-72
lines changed

11 files changed

+103
-72
lines changed

.verify-helper/timestamps.remote.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@
3737
"tests/library_checker_aizu_tests/data_structures/rmq_sparse_table.test.cpp": "2026-03-09 12:21:26 -0600",
3838
"tests/library_checker_aizu_tests/data_structures/rmq_sparse_table_inc.test.cpp": "2026-01-18 11:15:41 +0000",
3939
"tests/library_checker_aizu_tests/data_structures/simple_tree.test.cpp": "2026-03-01 19:36:27 -0700",
40-
"tests/library_checker_aizu_tests/data_structures/simple_tree_inc.test.cpp": "2026-03-01 19:36:27 -0700",
41-
"tests/library_checker_aizu_tests/data_structures/simple_tree_inc_line.test.cpp": "2026-03-01 19:36:27 -0700",
42-
"tests/library_checker_aizu_tests/data_structures/simple_tree_inc_walk.test.cpp": "2026-03-01 19:36:27 -0700",
40+
"tests/library_checker_aizu_tests/data_structures/simple_tree_inc.test.cpp": "2026-03-15 12:33:36 -0600",
41+
"tests/library_checker_aizu_tests/data_structures/simple_tree_inc_line.test.cpp": "2026-03-15 12:33:36 -0600",
42+
"tests/library_checker_aizu_tests/data_structures/simple_tree_inc_walk.test.cpp": "2026-03-15 12:33:36 -0600",
4343
"tests/library_checker_aizu_tests/data_structures/simple_tree_line.test.cpp": "2026-03-01 19:36:27 -0700",
4444
"tests/library_checker_aizu_tests/data_structures/simple_tree_walk.test.cpp": "2026-03-01 19:36:27 -0700",
4545
"tests/library_checker_aizu_tests/dsu/dsu.test.cpp": "2026-02-27 15:26:53 -0700",

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,14 @@
66
//! return vl + vr;
77
//! });
88
//! tree st(n, INT_MAX, ranges::min);
9-
//! int idx = st.max_right(l, r, [&](int value) {
9+
//! int idx = st.max_right(l, r, [&](int m, int value) {
10+
//! // value = op(a[l], a[l+1], ..., a[m-1])
1011
//! return value <= x;
1112
//! });
12-
//! // idx in [l, r]
13-
//! // f(op(a[l], a[l+1], ..., a[idx-1])) is true
14-
//! // f(op(a[l], a[l+1], ..., a[idx])) is false
15-
//! idx = st.min_left(l, r, [&](int value) {
13+
//! idx = st.min_left(l, r, [&](int m, int value) {
14+
//! // value = op(a[m], ..., a[r-2], a[r-1])
1615
//! return value <= x;
1716
//! });
18-
//! // idx in [l, r]
19-
//! // f(op(a[idx], ..., a[r-2], a[r-1])) is true
20-
//! // f(op(a[idx-1], ..., a[r-2], a[r-1])) is false
2117
//! @endcode
2218
//! @time O(n + q log n)
2319
//! @space O(n)
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
int max_right(int l, int r, const auto& f) {
1+
void max_right(int l, int r, const auto& f) {
22
for (T x = unit; l < r;) {
3-
int u = l + n, v = __lg(min(u & -u, r - l));
4-
if (T y = op(x, s[u >> v]); f(y)) l += 1 << v, x = y;
5-
else r = l + (1 << v) - 1;
3+
int u = l + n, v = __lg(min(u & -u, r - l)),
4+
m = l + (1 << v);
5+
if (T y = op(x, s[u >> v]); f(m, y)) l = m, x = y;
6+
else r = m - 1;
67
}
7-
return l;
88
}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
int min_left(int l, int r, const auto& f) {
1+
void min_left(int l, int r, const auto& f) {
22
for (T x = unit; l < r;) {
3-
int u = r + n, v = __lg(min(u & -u, r - l));
4-
if (T y = op(s[(u - 1) >> v], x); f(y))
5-
r -= 1 << v, x = y;
6-
else l = r - (1 << v) + 1;
3+
int u = r + n, v = __lg(min(u & -u, r - l)),
4+
m = r - (1 << v);
5+
if (T y = op(s[(u - 1) >> v], x); f(m, y))
6+
r = m, x = y;
7+
else l = m + 1;
78
}
8-
return r;
99
}

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,14 @@
55
//! return vl + vr;
66
//! });
77
//! tree st(a, ranges::min);
8-
//! int idx = st.max_right(l, r, [&](int value) {
8+
//! st.max_right(l, r, [&](int m, int value) {
9+
//! // value = op(a[l], a[l+1], ..., a[m])
910
//! return value <= x;
1011
//! });
11-
//! // idx in [l, r+1]
12-
//! // f(op(a[l], a[l+1], ..., a[idx-1])) is true
13-
//! // f(op(a[l], a[l+1], ..., a[idx])) is false
14-
//! idx = st.min_left(l, r, [&](int value) {
12+
//! st.min_left(l, r, [&](int m, int value) {
13+
//! // value = op(a[m], ..., a[r-1], a[r])
1514
//! return value <= x;
1615
//! });
17-
//! // idx in [l-1, r]
18-
//! // f(op(a[idx+1], ..., a[r-1], a[r])) is true
19-
//! // f(op(a[idx], ..., a[r-1], a[r])) is false
2016
//! @endcode
2117
//! @time O(n + q log n)
2218
//! @space O(n)
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
int max_right(int l, int r, const auto& f) {
2-
if (T x = s[l + n]; f(x))
1+
void max_right(int l, int r, const auto& f) {
2+
if (T x = s[l + n]; f(l, x))
33
for (l++; l <= r;) {
4-
int u = l + n, v = __lg(min(u & -u, r - l + 1));
5-
if (T y = op(x, s[u >> v]); f(y)) l += 1 << v, x = y;
6-
else r = l + (1 << v) - 2;
4+
int u = l + n, v = __lg(min(u & -u, r - l + 1)),
5+
m = l + (1 << v) - 1;
6+
if (T y = op(x, s[u >> v]); f(m, y))
7+
l = m + 1, x = y;
8+
else r = m - 1;
79
}
8-
return l;
910
}
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
int min_left(int l, int r, const auto& f) {
2-
if (T x = s[r + n]; f(x))
2+
if (T x = s[r + n]; f(r, x))
33
for (r--; l <= r;) {
4-
int u = r + 1 + n, v = __lg(min(u & -u, r - l + 1));
5-
if (T y = op(s[(u - 1) >> v], x); f(y))
6-
r -= 1 << v, x = y;
7-
else l = r - (1 << v) + 2;
4+
int u = r + 1 + n, v = __lg(min(u & -u, r - l + 1)),
5+
m = r - (1 << v) + 1;
6+
if (T y = op(s[(u - 1) >> v], x); f(m, y))
7+
r = m - 1, x = y;
8+
else l = m + 1;
89
}
910
return r;
1011
}

tests/library_checker_aizu_tests/data_structures/simple_tree_inc_line.test.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,39 +30,51 @@ int main() {
3030
array<int, 2> res = st.query(l, r);
3131
{
3232
array<int, 2> walk_res = {1, 0};
33-
int idx = st.max_right(l, r,
34-
[&](const array<int, 2>& curr_line) -> bool {
33+
int idx = -1;
34+
st.max_right(l, r,
35+
[&](int m,
36+
const array<int, 2>& curr_line) -> bool {
37+
idx = m;
3538
walk_res = curr_line;
3639
return 1;
3740
});
3841
assert(res == walk_res);
39-
assert(idx == r + 1);
42+
assert(idx == r);
4043
}
4144
{
4245
array<int, 2> walk_res = unit;
43-
int idx = st.max_right(l, r,
44-
[&](const array<int, 2>& curr_line) -> bool {
46+
int idx = -1;
47+
st.max_right(l, r,
48+
[&](int m,
49+
const array<int, 2>& curr_line) -> bool {
4550
walk_res = curr_line;
51+
idx = m;
4652
return 0;
4753
});
4854
assert(walk_res == st.query(l, l));
4955
assert(idx == l);
5056
}
5157
{
5258
array<int, 2> walk_res = unit;
53-
int idx = st.min_left(l, r,
54-
[&](const array<int, 2>& curr_line) -> bool {
59+
int idx = -1;
60+
st.min_left(l, r,
61+
[&](int m,
62+
const array<int, 2>& curr_line) -> bool {
5563
walk_res = curr_line;
64+
idx = m;
5665
return 1;
5766
});
5867
assert(walk_res == res);
59-
assert(idx == l - 1);
68+
assert(idx == l);
6069
}
6170
{
6271
array<int, 2> walk_res = unit;
63-
int idx = st.min_left(l, r,
64-
[&](const array<int, 2>& curr_line) -> bool {
72+
int idx = -1;
73+
st.min_left(l, r,
74+
[&](int m,
75+
const array<int, 2>& curr_line) -> bool {
6576
walk_res = curr_line;
77+
idx = m;
6678
return 0;
6779
});
6880
assert(walk_res == st.query(r, r));

tests/library_checker_aizu_tests/data_structures/simple_tree_inc_walk.test.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,20 @@ int main() {
2222
cout << st.query(k, k) << '\n';
2323
} else if (type == 3) {
2424
// returns first element in [k,n-1] such that mx > 0
25-
int idx = st.max_right(k, n - 1,
26-
[&](int mx) { return mx == 0; });
27-
if (idx == n) idx = -1;
25+
int idx = -1;
26+
st.max_right(k, n - 1, [&](int m, int mx) {
27+
if (mx == 0) return 1;
28+
idx = m;
29+
return 0;
30+
});
2831
cout << idx << '\n';
2932
} else {
3033
assert(type == 4);
31-
cout << st.min_left(0, k, [&](int mx) {
32-
return mx == 0;
34+
int idx = -1;
35+
cout << st.min_left(0, k, [&](int m, int mx) {
36+
if (mx == 0) return 1;
37+
idx = m;
38+
return 0;
3339
}) << '\n';
3440
}
3541
}

tests/library_checker_aizu_tests/data_structures/simple_tree_line.test.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,43 +34,55 @@ int main() {
3434
array<int, 2> res = st.query(l, r);
3535
{
3636
array<int, 2> walk_res = {1, 0};
37-
int idx = st.max_right(l, r,
38-
[&](const array<int, 2>& curr_line) -> bool {
37+
int idx = -1;
38+
st.max_right(l, r,
39+
[&](int m,
40+
const array<int, 2>& curr_line) -> bool {
3941
walk_res = curr_line;
42+
idx = m;
4043
return 1;
4144
});
4245
assert(res == walk_res);
4346
assert(idx == r);
4447
}
4548
{
4649
array<int, 2> walk_res = unit;
47-
int idx = st.max_right(l, r,
48-
[&](const array<int, 2>& curr_line) -> bool {
50+
int idx = -1;
51+
st.max_right(l, r,
52+
[&](int m,
53+
const array<int, 2>& curr_line) -> bool {
4954
walk_res = curr_line;
55+
idx = m;
5056
return 0;
5157
});
5258
assert(walk_res == st.query(l, l + 1));
53-
assert(idx == l);
59+
assert(idx == l + 1);
5460
}
5561
{
5662
array<int, 2> walk_res = unit;
57-
int idx = st.min_left(l, r,
58-
[&](const array<int, 2>& curr_line) -> bool {
63+
int idx = -1;
64+
st.min_left(l, r,
65+
[&](int m,
66+
const array<int, 2>& curr_line) -> bool {
5967
walk_res = curr_line;
68+
idx = m;
6069
return 1;
6170
});
6271
assert(walk_res == res);
6372
assert(idx == l);
6473
}
6574
{
6675
array<int, 2> walk_res = unit;
67-
int idx = st.min_left(l, r,
68-
[&](const array<int, 2>& curr_line) -> bool {
76+
int idx = -1;
77+
st.min_left(l, r,
78+
[&](int m,
79+
const array<int, 2>& curr_line) -> bool {
6980
walk_res = curr_line;
81+
idx = m;
7082
return 0;
7183
});
7284
assert(walk_res == st.query(r - 1, r));
73-
assert(idx == r);
85+
assert(idx == r - 1);
7486
}
7587
cout << (1LL * res[0] * x + res[1]) % mod << '\n';
7688
}

0 commit comments

Comments
 (0)