use crate::{LazySegTree, LazySegTreeSpec};
use min_max_traits::Max as ConstUpperBound;
use std::marker::PhantomData;
use std::ops::Add;
pub struct LazySegTreeAddMinSpec<T>(PhantomData<T>);
impl<T> LazySegTreeSpec for LazySegTreeAddMinSpec<T>
where
T: Clone + Add<Output = T> + ConstUpperBound + Ord,
{
type T = T;
type U = T;
const ID: Self::T = <T as ConstUpperBound>::MAX;
fn op_on_data(d1: &mut Self::T, d2: &Self::T) {
if *d1 > *d2 {
*d1 = d2.clone();
}
}
fn op_on_update(u1: &mut Self::U, u2: &Self::U) {
*u1 = u1.clone() + u2.clone();
}
fn op_update_on_data(u: &Self::U, d: &mut Self::T, _size: usize) {
*d = d.clone() + u.clone();
}
}
pub type LazySegTreeAddMin<T> = LazySegTree<LazySegTreeAddMinSpec<T>>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add_min_basic_operations() {
let values = vec![5, 2, 8, 1, 9, 3];
let tree = LazySegTreeAddMin::<i32>::from_vec(values);
assert_eq!(tree.query(..), 1); assert_eq!(tree.query(1..4), 1); assert_eq!(tree.query(..1), 5); assert_eq!(tree.query(4..6), 3); assert_eq!(tree.query(2..2), i32::MAX); }
#[test]
fn test_add_min_range_updates() {
let values = vec![10, 20, 30, 40, 50];
let mut tree = LazySegTreeAddMin::<i32>::from_vec(values);
assert_eq!(tree.query(..), 10);
tree.update(1..4, 5);
assert_eq!(tree.query(..), 10); assert_eq!(tree.query(1..4), 25);
tree.update(..3, -15);
assert_eq!(tree.query(..), -5); assert_eq!(tree.query(..3), -5); }
#[test]
fn test_add_min_overlapping_updates() {
let values = vec![1, 1, 1, 1, 1];
let mut tree = LazySegTreeAddMin::<i32>::from_vec(values);
assert_eq!(tree.query(..), 1);
tree.update(..3, 2); tree.update(2..5, -1); tree.update(1..4, 1);
assert_eq!(tree.query(..1), 3);
assert_eq!(tree.query(1..2), 4);
assert_eq!(tree.query(2..3), 3);
assert_eq!(tree.query(3..4), 1);
assert_eq!(tree.query(4..5), 0);
assert_eq!(tree.query(..), 0);
}
#[test]
fn test_add_min_negative_updates() {
let values = vec![10, 20, 30, 40, 50];
let mut tree = LazySegTreeAddMin::<i32>::from_vec(values);
assert_eq!(tree.query(..), 10);
tree.update(1..4, -5);
assert_eq!(tree.query(..), 10); assert_eq!(tree.query(1..4), 15);
tree.update(..2, 15); assert_eq!(tree.query(..2), 25); assert_eq!(tree.query(..), 25); }
#[test]
fn test_add_min_edge_cases() {
let single = vec![42];
let mut tree_single = LazySegTreeAddMin::<i32>::from_vec(single);
assert_eq!(tree_single.query(..), 42);
tree_single.update(..1, 8);
assert_eq!(tree_single.query(..), 50);
let values = vec![1, 2, 3, 4, 5];
let mut tree = LazySegTreeAddMin::<i32>::from_vec(values);
let original_min = tree.query(..);
tree.update(2..2, 100); assert_eq!(tree.query(..), original_min); }
#[test]
fn test_add_min_large_tree() {
let size = 1000;
let values = vec![1i32; size]; let mut tree = LazySegTreeAddMin::<i32>::from_vec(values);
assert_eq!(tree.query(..), 1);
tree.update(..size / 2, 1);
assert_eq!(tree.query(..), 1);
tree.update(size / 2.., -2);
assert_eq!(tree.query(..), -1); assert_eq!(tree.query(size / 2..), -1);
}
#[test]
#[should_panic(expected = "overflow")]
fn test_add_min_new_empty_tree_should_panic() {
let mut tree = LazySegTreeAddMin::<i32>::new(5);
assert_eq!(tree.query(..), i32::MAX);
tree.update(1..4, 10);
}
}