Skip to content

Commit 336bf18

Browse files
Added a test
1 parent 61cd506 commit 336bf18

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

src/lazysegtree.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,106 @@ where
285285
self.lz[k] = F::identity_map();
286286
}
287287
}
288+
289+
#[cfg(test)]
290+
mod tests {
291+
use crate::{LazySegtree, MapMonoid, Max};
292+
293+
struct MaxAdd;
294+
impl MapMonoid for MaxAdd {
295+
type M = Max<i32>;
296+
type F = i32;
297+
298+
fn identity_map() -> Self::F {
299+
0
300+
}
301+
302+
fn mapping(f: i32, x: i32) -> i32 {
303+
f + x
304+
}
305+
306+
fn composition(f: i32, g: i32) -> i32 {
307+
f + g
308+
}
309+
}
310+
311+
#[test]
312+
fn test_max_add_lazy_segtree() {
313+
let base = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
314+
let n = base.len();
315+
let mut segtree: LazySegtree<MaxAdd> = base.clone().into();
316+
check_segtree(&base, &mut segtree);
317+
318+
let mut segtree = LazySegtree::<MaxAdd>::new(n);
319+
let mut internal = vec![i32::min_value(); n];
320+
for i in 0..n {
321+
segtree.set(i, base[i]);
322+
internal[i] = base[i];
323+
check_segtree(&internal, &mut segtree);
324+
}
325+
326+
segtree.set(6, 5);
327+
internal[6] = 5;
328+
check_segtree(&internal, &mut segtree);
329+
330+
segtree.apply(5, 1);
331+
internal[5] += 1;
332+
check_segtree(&internal, &mut segtree);
333+
334+
segtree.set(6, 0);
335+
internal[6] = 0;
336+
check_segtree(&internal, &mut segtree);
337+
338+
segtree.apply_range(3, 8, 2);
339+
internal[3..8].iter_mut().for_each(|e| *e += 2);
340+
check_segtree(&internal, &mut segtree);
341+
}
342+
343+
//noinspection DuplicatedCode
344+
fn check_segtree(base: &[i32], segtree: &mut LazySegtree<MaxAdd>) {
345+
let n = base.len();
346+
#[allow(clippy::needless_range_loop)]
347+
for i in 0..n {
348+
assert_eq!(segtree.get(i), base[i]);
349+
}
350+
for i in 0..=n {
351+
for j in i..=n {
352+
assert_eq!(
353+
segtree.prod(i, j),
354+
base[i..j].iter().max().copied().unwrap_or(i32::min_value())
355+
);
356+
}
357+
}
358+
assert_eq!(
359+
segtree.all_prod(),
360+
base.iter().max().copied().unwrap_or(i32::min_value())
361+
);
362+
for k in 0..=10 {
363+
let f = |x| x < k;
364+
for i in 0..=n {
365+
assert_eq!(
366+
Some(segtree.max_right(i, f)),
367+
(i..=n)
368+
.filter(|&j| f(base[i..j]
369+
.iter()
370+
.max()
371+
.copied()
372+
.unwrap_or(i32::min_value())))
373+
.max()
374+
);
375+
}
376+
for j in 0..=n {
377+
assert_eq!(
378+
Some(segtree.min_left(j, f)),
379+
(0..=j)
380+
.filter(|&i| f(base[i..j]
381+
.iter()
382+
.max()
383+
.copied()
384+
.unwrap_or(i32::min_value())))
385+
.min()
386+
);
387+
}
388+
}
389+
}
390+
}

src/segtree.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ mod test {
224224
check_segtree(&internal, &segtree);
225225
}
226226

227+
//noinspection DuplicatedCode
227228
fn check_segtree(base: &[i32], segtree: &Segtree<Max<i32>>) {
228229
let n = base.len();
229230
#[allow(clippy::needless_range_loop)]

0 commit comments

Comments
 (0)