Skip to content

Commit 7f70828

Browse files
Added "Max" monoid and a test
1 parent db3e57f commit 7f70828

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

src/segtree.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
11
use crate::internal_bit::ceil_pow2;
2+
use crate::internal_type_traits::Integral;
3+
use std::cmp::max;
4+
use std::marker::PhantomData;
25

36
// TODO Should I split monoid-related traits to another module?
47
pub trait Monoid {
58
type S: Copy;
69
fn identity() -> Self::S;
710
fn binary_operation(a: Self::S, b: Self::S) -> Self::S;
811
}
12+
pub struct Max<S>(PhantomData<fn() -> S>);
13+
14+
// TODO We should not restrict to integral
15+
impl<S> Monoid for Max<S>
16+
where
17+
S: Integral,
18+
{
19+
type S = S;
20+
21+
fn identity() -> Self::S {
22+
S::min_value()
23+
}
24+
25+
fn binary_operation(a: Self::S, b: Self::S) -> Self::S {
26+
max(a, b)
27+
}
28+
}
929

1030
impl<M: Monoid> Segtree<M> {
1131
pub fn new(n: usize) -> Segtree<M> {
@@ -149,6 +169,16 @@ impl<M: Monoid> Segtree<M> {
149169
}
150170
}
151171

172+
// Maybe we can use this someday
173+
// ```
174+
// for i in 0..=self.log {
175+
// for j in 0..1 << i {
176+
// print!("{}\t", self.d[(1 << i) + j]);
177+
// }
178+
// println!();
179+
// }
180+
// ```
181+
152182
#[derive(Default)]
153183
pub struct Segtree<M>
154184
where
@@ -160,3 +190,80 @@ where
160190
log: usize,
161191
d: Vec<M::S>,
162192
}
193+
194+
#[cfg(test)]
195+
mod test {
196+
use crate::segtree::Max;
197+
use crate::Segtree;
198+
199+
#[test]
200+
fn test_max_from_vec() {
201+
let base = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
202+
let n = base.len();
203+
let segtree: Segtree<Max<_>> = base.clone().into();
204+
check_segtree(&base, &segtree);
205+
206+
let mut segtree = Segtree::<Max<_>>::new(n);
207+
let mut internal = vec![i32::min_value(); n];
208+
for i in 0..n {
209+
segtree.set(i, base[i]);
210+
internal[i] = base[i];
211+
check_segtree(&internal, &segtree);
212+
}
213+
214+
segtree.set(6, 5);
215+
internal[6] = 5;
216+
check_segtree(&internal, &segtree);
217+
218+
segtree.set(6, 0);
219+
internal[6] = 0;
220+
check_segtree(&internal, &segtree);
221+
}
222+
223+
fn check_segtree(base: &[i32], segtree: &Segtree<Max<i32>>) {
224+
let n = base.len();
225+
#[allow(clippy::needless_range_loop)]
226+
for i in 0..n {
227+
assert_eq!(segtree.get(i), base[i]);
228+
}
229+
for i in 0..=n {
230+
for j in i..=n {
231+
assert_eq!(
232+
segtree.prod(i, j),
233+
base[i..j].iter().max().copied().unwrap_or(i32::min_value())
234+
);
235+
}
236+
}
237+
assert_eq!(
238+
segtree.all_prod(),
239+
base.iter().max().copied().unwrap_or(i32::min_value())
240+
);
241+
for k in 0..=10 {
242+
let f = |x| x < k;
243+
for i in 0..=n {
244+
assert_eq!(
245+
Some(segtree.max_right(i, f)),
246+
(i..=n)
247+
.filter(|&j| f(base[i..j]
248+
.iter()
249+
.max()
250+
.copied()
251+
.unwrap_or(i32::min_value())))
252+
.max()
253+
);
254+
}
255+
for j in 0..=n {
256+
assert_eq!(
257+
Some(segtree.min_left(j, f)),
258+
(0..=j)
259+
.filter(|&i| f(base[i..j]
260+
.iter()
261+
.max()
262+
.copied()
263+
.unwrap_or(i32::min_value())))
264+
.min()
265+
);
266+
}
267+
}
268+
}
269+
}

0 commit comments

Comments
 (0)