haar_lib/algo/
shakutori.rs

1//! 尺取り法
2//!
3//! # Problems
4//! - <https://atcoder.jp/contests/abc038/tasks/abc038_c>
5//! - <https://atcoder.jp/contests/arc022/tasks/arc022_2>
6//! - <https://atcoder.jp/contests/abc444/tasks/abc444_e>
7
8/// 尺取り法
9///
10/// * remove_left - `|l: usize| {尺取りの左端を縮めたときの操作}`
11/// * can_append_right - `|l: usize, r: usize| {l..r+1が条件を満たすかを判定}`
12/// * append_right - `|r: usize| {尺取りの右端を進めたときの操作}`
13pub fn shakutori(
14    n: usize,
15    mut remove_left: impl FnMut(usize),
16    can_append_right: impl Fn(usize, usize) -> bool,
17    mut append_right: impl FnMut(usize),
18    mut f: impl FnMut(usize, usize),
19) {
20    let mut right = 0;
21
22    for left in 0..n {
23        if right < left {
24            right = left;
25        }
26
27        while right < n {
28            if can_append_right(left, right) {
29                append_right(right);
30                right += 1;
31            } else {
32                break;
33            }
34        }
35
36        f(left, right);
37
38        if left < right {
39            remove_left(left);
40        }
41    }
42}