#![doc = include_str!("./../README.md")]
mod modify_op;
mod seg_node;
use seg_node::SegNode;
use std::ops::{Add, Mul, Range};
pub use modify_op::ModifyOp;
pub struct SegTree<T, Op> {
point_cnt: usize,
root: SegNode<T, Op>,
}
impl<T, Op> SegTree<T, Op>
where
T: Clone,
for<'x> &'x T: Add<Output = T> + Mul<usize, Output = T>,
Op: ModifyOp<T>,
{
pub fn new(
point_cnt: usize,
default_data_for_single_point: T,
) -> Self {
assert!(point_cnt > 0);
Self {
point_cnt,
root: SegNode::from_same_point_data(
default_data_for_single_point,
),
}
}
pub fn with_points(point_data: &[T]) -> Self {
assert!(!point_data.is_empty());
Self {
point_cnt: point_data.len(),
root: SegNode::with_points(point_data),
}
}
pub fn point_cnt(&self) -> usize {
self.point_cnt
}
pub fn modify_point(&mut self, point_idx: usize, op: &Op) {
self.modify(&(point_idx..point_idx + 1), op);
}
pub fn modify(&mut self, target_range: &Range<usize>, op: &Op) {
if target_range.is_empty() {
return;
}
assert!(target_range.end <= self.point_cnt);
self.root.modify(&(0..self.point_cnt), target_range, op);
}
pub fn query_point(&mut self, point_idx: usize) -> T {
self.query(&(point_idx..point_idx + 1))
}
pub fn query(&mut self, target_range: &Range<usize>) -> T {
assert!(target_range.end <= self.point_cnt);
assert!(!target_range.is_empty());
self.root.query(&(0..self.point_cnt), target_range)
}
}