use crate::{SegTree, SegTreeSpec};
use num_traits::ConstZero;
use std::marker::PhantomData;
use std::ops::AddAssign;
pub struct SegTreeSumSpec<T>(PhantomData<T>);
impl<T> SegTreeSpec for SegTreeSumSpec<T>
where
T: Clone + ConstZero + AddAssign<T>,
{
type T = T;
const ID: Self::T = <T as ConstZero>::ZERO;
fn op(a: &mut Self::T, b: &Self::T) {
*a += b.clone();
}
}
pub type SegTreeSum<T> = SegTree<SegTreeSumSpec<T>>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sum_basic_operations() {
let values = vec![1, 2, 3, 4, 5];
let tree = SegTreeSum::<i32>::from_slice(&values);
assert_eq!(tree.query(..), 15); assert_eq!(tree.query(1..4), 9); assert_eq!(tree.query(..1), 1); assert_eq!(tree.query(4..5), 5); assert_eq!(tree.query(2..2), 0); }
#[test]
fn test_sum_updates() {
let values = vec![10, 20, 30, 40, 50];
let mut tree = SegTreeSum::<i32>::from_slice(&values);
assert_eq!(tree.query(..), 150);
tree.update(2, 100);
assert_eq!(tree.query(..), 220); assert_eq!(tree.query(2..3), 100); assert_eq!(tree.query(1..4), 160);
tree.update(0, 5);
assert_eq!(tree.query(..), 215); assert_eq!(tree.query(..2), 25); }
#[test]
fn test_sum_with_different_types() {
let values_i64 = vec![1000000000_i64, 2000000000, 3000000000];
let tree_i64 = SegTreeSum::<i64>::from_slice(&values_i64);
assert_eq!(tree_i64.query(..), 6000000000);
let values_f64 = vec![1.5, 2.5, 3.5, 4.5];
let tree_f64 = SegTreeSum::<f64>::from_slice(&values_f64);
assert!((tree_f64.query(..) - 12.0).abs() < 1e-10);
assert!((tree_f64.query(1..3) - 6.0).abs() < 1e-10);
}
#[test]
fn test_sum_edge_cases() {
let single = vec![42];
let tree_single = SegTreeSum::<i32>::from_slice(&single);
assert_eq!(tree_single.query(..), 42);
assert_eq!(tree_single.query(..0), 0);
let values = vec![1, 2, 3, 4, 5, 6, 7, 8];
let tree = SegTreeSum::<i32>::from_slice(&values);
assert_eq!(tree.query(3..3), 0); assert_eq!(tree.query(..0), 0); assert_eq!(tree.query(8..), 0); }
#[test]
fn test_sum_large_tree() {
let size: i32 = 1000;
let values: Vec<i32> = (1..=size).collect();
let mut tree = SegTreeSum::<i32>::from_slice(&values);
assert_eq!(tree.query(..), 500500);
assert_eq!(tree.query(..500), 125250);
assert_eq!(tree.query(500..), 375250);
tree.update(499, 0); assert_eq!(tree.query(..), 500000); assert_eq!(tree.query(..500), 124750); }
#[test]
fn test_sum_zero_values() {
let values = vec![0, 0, 0, 0, 0];
let mut tree = SegTreeSum::<i32>::from_slice(&values);
assert_eq!(tree.query(..), 0);
assert_eq!(tree.query(1..4), 0);
tree.update(2, 10);
assert_eq!(tree.query(..), 10);
assert_eq!(tree.query(2..3), 10);
assert_eq!(tree.query(..2), 0);
assert_eq!(tree.query(3..5), 0);
}
#[test]
fn test_sum_negative_values() {
let values = vec![-5, -3, -1, 2, 4];
let mut tree = SegTreeSum::<i32>::from_slice(&values);
assert_eq!(tree.query(..), -3); assert_eq!(tree.query(..3), -9); assert_eq!(tree.query(3..5), 6);
tree.update(0, 10); assert_eq!(tree.query(..), 12); }
#[test]
fn test_sum_new_empty_tree() {
let mut tree = SegTreeSum::<i32>::new(5);
assert_eq!(tree.query(..), 0);
assert_eq!(tree.query(2..4), 0);
tree.update(1, 10);
tree.update(3, 20);
assert_eq!(tree.query(..), 30); assert_eq!(tree.query(1..4), 30);
assert_eq!(tree.query(..2), 10);
}
}