haar_lib/ds/
sparse_table.rs1use crate::algebra::traits::*;
4use crate::misc::range::range_bounds_to_range;
5use std::{cmp::min, ops::RangeBounds};
6
7pub struct SparseTable<A: Semilattice> {
9 semilattice: A,
10 data: Vec<Vec<A::Element>>,
11 log_table: Vec<usize>,
12 original_size: usize,
13}
14
15impl<A: Semilattice> SparseTable<A>
16where
17 A::Element: Clone + Default,
18{
19 pub fn new(semilattice: A, s: Vec<A::Element>) -> Self {
23 let n = s.len();
24 let logn = n.next_power_of_two().trailing_zeros() as usize + 1;
25
26 let mut data = vec![vec![A::Element::default(); n]; logn];
27
28 data[0] = s;
29
30 for i in 1..logn {
31 for j in 0..n {
32 data[i][j] = semilattice.op(
33 data[i - 1][j].clone(),
34 data[i - 1][min(n - 1, j + (1 << (i - 1)))].clone(),
35 );
36 }
37 }
38
39 let mut log_table = vec![0; n + 1];
40 for i in 2..=n {
41 log_table[i] = log_table[i >> 1] + 1;
42 }
43
44 Self {
45 semilattice,
46 data,
47 log_table,
48 original_size: n,
49 }
50 }
51
52 pub fn fold(&self, range: impl RangeBounds<usize>) -> Option<A::Element> {
54 let (l, r) = range_bounds_to_range(range, 0, self.original_size);
55
56 if l >= r {
57 None
58 } else {
59 let k = self.log_table[r - l];
60 Some(
61 self.semilattice
62 .op(self.data[k][l].clone(), self.data[k][r - (1 << k)].clone()),
63 )
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use std::fmt::Debug;
71
72 use crate::algebra::{
73 bit::{BitAnd, BitOr},
74 min_max::{Max, Min},
75 };
76
77 use super::*;
78 use rand::Rng;
79
80 fn test<A>(a: A, s: Vec<A::Element>)
81 where
82 A: Semilattice + Identity + Clone,
83 A::Element: Copy + Default + PartialEq + Debug,
84 {
85 let st = SparseTable::new(a.clone(), s.clone());
86
87 for l in 0..s.len() {
88 for r in l..=s.len() {
89 let ans = &s[l..r].iter().cloned().fold_m(&a);
90 assert_eq!(*ans, st.fold(l..r).unwrap_or(a.id()));
91 }
92 }
93 }
94
95 #[test]
96 fn test_max() {
97 let mut rng = rand::thread_rng();
98 let n = 100;
99 let s = std::iter::repeat_with(|| rng.gen::<u64>())
100 .take(n)
101 .collect::<Vec<_>>();
102 test(Max::<u64>::new(), s);
103 }
104
105 #[test]
106 fn test_min() {
107 let mut rng = rand::thread_rng();
108 let n = 100;
109 let s = std::iter::repeat_with(|| rng.gen::<u64>())
110 .take(n)
111 .collect::<Vec<_>>();
112 test(Min::<u64>::new(), s);
113 }
114
115 #[test]
116 fn test_bitand() {
117 let mut rng = rand::thread_rng();
118 let n = 100;
119 let s = std::iter::repeat_with(|| rng.gen::<u64>())
120 .take(n)
121 .collect::<Vec<_>>();
122 test(BitAnd::<u64>::new(), s);
123 }
124
125 #[test]
126 fn test_bitor() {
127 let mut rng = rand::thread_rng();
128 let n = 100;
129 let s = std::iter::repeat_with(|| rng.gen::<u64>())
130 .take(n)
131 .collect::<Vec<_>>();
132 test(BitOr::<u64>::new(), s);
133 }
134}