competitive_library/structure/
sparse_table.rs1use std::ops::Range;
7
8pub trait Band {
10 type T: Clone;
11 fn operate(a: &Self::T, b: &Self::T) -> Self::T;
12}
13
14pub struct Min {}
16impl Band for Min {
17 type T = i64;
18
19 fn operate(a: &Self::T, b: &Self::T) -> Self::T {
20 *a.min(b)
21 }
22}
23
24pub struct SparseTable<B: Band> {
26 table: Vec<Vec<B::T>>,
27}
28
29impl<B: Band> SparseTable<B> {
30 pub fn new(v: &[B::T]) -> Self {
32 let mut table = vec![v.to_vec()];
33
34 for i in 1..64 - v.len().leading_zeros() as usize {
35 let mut tmp = vec![];
36 for j in 0..=v.len() - (1 << i) {
37 tmp.push(B::operate(
38 &table[i - 1][j],
39 &table[i - 1][j + (1 << (i - 1))],
40 ));
41 }
42 table.push(tmp);
43 }
44
45 SparseTable { table }
46 }
47
48 pub fn fold(&self, range: Range<usize>) -> B::T {
51 let i = 64 - (range.end - range.start).leading_zeros() as usize - 1;
52 B::operate(
53 &self.table[i][range.start],
54 &self.table[i][range.end - (1 << i)],
55 )
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 #[test]
63 fn test_sparse_table() {
64 let a = SparseTable::<Min>::new(&[2, 10, 1, 100]);
65 for (l, r, ans) in [
66 (0, 1, 2),
67 (0, 2, 2),
68 (0, 3, 1),
69 (0, 4, 1),
70 (1, 2, 10),
71 (1, 3, 1),
72 (1, 4, 1),
73 (2, 3, 1),
74 (2, 4, 1),
75 (3, 4, 100),
76 ]
77 .iter()
78 {
79 assert_eq!(a.fold(*l..*r), *ans);
80 }
81 }
82}