use crate::{LazySegTree, LazySegTreeSpec};
use min_max_traits::Min as ConstLowerBound;
use std::marker::PhantomData;
use std::ops::Add;
pub struct LazySegTreeAddMaxSpec<T>(PhantomData<T>);
impl<T> LazySegTreeSpec for LazySegTreeAddMaxSpec<T>
where
T: Clone + Add<Output = T> + ConstLowerBound + Ord,
{
type T = T;
type U = T;
const ID: Self::T = <T as ConstLowerBound>::MIN;
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 LazySegTreeAddMax<T> = LazySegTree<LazySegTreeAddMaxSpec<T>>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add_max_basic_operations() {
let values = vec![1i32, 3, 2, 5, 4];
let tree = LazySegTreeAddMax::<i32>::from_vec(values);
assert_eq!(tree.query(..), 5); assert_eq!(tree.query(1..4), 5); assert_eq!(tree.query(..1), 1); assert_eq!(tree.query(3..4), 5); assert_eq!(tree.query(2..2), i32::MIN); }
#[test]
fn test_add_max_range_updates() {
let values = vec![10i32, 20, 30, 40, 50];
let mut tree = LazySegTreeAddMax::<i32>::from_vec(values);
assert_eq!(tree.query(..), 50);
tree.update(1..4, 5);
assert_eq!(tree.query(..), 50); assert_eq!(tree.query(1..4), 45); assert_eq!(tree.query(..2), 25);
tree.update(..3, 20);
assert_eq!(tree.query(..3), 55); assert_eq!(tree.query(..), 55); }
#[test]
fn test_add_max_overlapping_updates() {
let values = vec![1i32, 1, 1, 1, 1]; let mut tree = LazySegTreeAddMax::<i32>::from_vec(values);
assert_eq!(tree.query(..), 1);
tree.update(..3, 2); tree.update(2..5, 4); tree.update(1..4, 1);
assert_eq!(tree.query(..1), 3); assert_eq!(tree.query(1..2), 4); assert_eq!(tree.query(2..3), 8); assert_eq!(tree.query(3..4), 6); assert_eq!(tree.query(4..5), 5); assert_eq!(tree.query(..), 8); }
#[test]
fn test_add_max_negative_updates() {
let values = vec![10i32, 20, 30, 40, 50];
let mut tree = LazySegTreeAddMax::<i32>::from_vec(values);
assert_eq!(tree.query(..), 50);
tree.update(1..4, -5);
assert_eq!(tree.query(..), 50); assert_eq!(tree.query(1..4), 35);
tree.update(..2, -15); assert_eq!(tree.query(..2), 0); assert_eq!(tree.query(..), 50); }
#[test]
fn test_add_max_edge_cases() {
let single = vec![42i32];
let mut tree_single = LazySegTreeAddMax::<i32>::from_vec(single);
assert_eq!(tree_single.query(..), 42);
tree_single.update(..1, 8);
assert_eq!(tree_single.query(..), 50);
let values = vec![1i32, 2, 3, 4, 5];
let mut tree = LazySegTreeAddMax::<i32>::from_vec(values);
let original_max = tree.query(..);
tree.update(2..2, 100); assert_eq!(tree.query(..), original_max); }
#[test]
fn test_add_max_large_tree() {
let size = 1000;
let values: Vec<i64> = (1..=size as i64).collect(); let mut tree = LazySegTreeAddMax::<i64>::from_vec(values);
assert_eq!(tree.query(..), size as i64);
tree.update(..size / 2, 1000);
assert_eq!(tree.query(..), 1500); assert_eq!(tree.query(..size / 2), 1500); assert_eq!(tree.query(size / 2..), 1000); }
#[test]
fn test_add_max_new_empty_tree() {
let mut tree = LazySegTreeAddMax::<i32>::new(5);
assert_eq!(tree.query(..), i32::MIN);
tree.update(1..4, 10);
assert_eq!(tree.query(..), i32::MIN + 10);
assert_eq!(tree.query(4..5), i32::MIN);
tree.update(..3, 5);
assert_eq!(tree.query(..), i32::MIN + 15);
assert_eq!(tree.query(3..), i32::MIN + 10);
}
#[test]
fn test_add_max_zero_updates() {
let values = vec![5i32, 10, 15, 20];
let mut tree = LazySegTreeAddMax::<i32>::from_vec(values);
let original_max = tree.query(..4);
tree.update(..4, 0);
assert_eq!(tree.query(..4), original_max);
tree.update(1..3, 0);
assert_eq!(tree.query(..4), original_max);
}
#[test]
fn test_add_max_all_negative() {
let values = vec![-10i32, -5, -15, -3, -8];
let mut tree = LazySegTreeAddMax::<i32>::from_vec(values);
assert_eq!(tree.query(..), -3);
tree.update(1..4, 10);
assert_eq!(tree.query(..), 7); assert_eq!(tree.query(1..4), 7); }
#[test]
fn test_add_max_stress_test() {
let size = 100;
let mut tree = LazySegTreeAddMax::<i32>::new(size);
let mut vec = vec![i32::MIN; size];
for i in 0..50 {
let left = i * 2;
let right = std::cmp::min((i + 1) * 2 + 10, size);
tree.update(left..right, (i + 1) as i32);
for item in &mut vec[left..right] {
*item += (i + 1) as i32;
}
}
let total_max = tree.query(..);
let expected_max = vec.iter().max().unwrap_or(&i32::MIN);
assert_eq!(
total_max, *expected_max,
"Expected max value: {}",
expected_max
);
for i in 0..10 {
let left = i * 10;
let right = std::cmp::min((i + 1) * 10, size);
let range_max = tree.query(left..right);
let expected_max = vec[left..right].iter().max().unwrap_or(&i32::MIN);
assert_eq!(range_max, *expected_max);
}
}
}