dsalgo 0.3.10

A package for Datastructures and Algorithms.
Documentation
use crate::bit_length_with_count_leading_zeros_usize::bit_length;

pub trait Monoid {
    type T;

    fn op(
        &self,
        l: Self::T,
        r: Self::T,
    ) -> Self::T;

    fn e(&self) -> Self::T;
}

pub struct DualSegtree<G: Monoid> {
    g: G,
    node: Vec<G::T>,
    size: usize,
}

impl<G: Monoid> DualSegtree<G>
where
    G::T: Clone,
{
    pub fn new(
        g: G,
        size: usize,
    ) -> Self {
        assert!(size > 0);

        let n = size.next_power_of_two();

        let node = vec![g.e(); n << 1];

        Self { g, node, size }
    }

    pub fn size(&self) -> usize {
        self.size
    }

    fn n(&self) -> usize {
        self.node.len() >> 1
    }

    fn height(&self) -> usize {
        bit_length(self.n())
    }

    fn operate_node(
        &mut self,
        i: usize,
        x: G::T,
    ) {
        self.node[i] = self.g.op(self.node[i].clone(), x);
    }

    fn propagate(
        &mut self,
        i: usize,
    ) {
        self.operate_node(i << 1, self.node[i].clone());

        self.operate_node(i << 1 | 1, self.node[i].clone());

        self.node[i] = self.g.e();
    }

    fn pull(
        &mut self,
        i: usize,
    ) {
        for j in (1..self.height()).rev() {
            self.propagate(i >> j);
        }
    }

    pub fn get(
        &mut self,
        mut i: usize,
    ) -> &mut G::T {
        assert!(i < self.size());

        i += self.n();

        self.pull(i);

        &mut self.node[i]
    }

    pub fn operate(
        &mut self,
        mut l: usize,
        mut r: usize,
        x: G::T,
    ) {
        assert!(l <= r && r <= self.size());

        let n = self.n();

        l += n;

        r += n;

        self.pull(l >> l.trailing_zeros());

        self.pull((r >> r.trailing_zeros()) - 1);

        while l < r {
            if l & 1 == 1 {
                self.operate_node(l, x.clone());

                l += 1;
            }

            if r & 1 == 1 {
                r -= 1;

                self.operate_node(r, x.clone());
            }

            l >>= 1;

            r >>= 1;
        }
    }
}

#[cfg(test)]

mod tests {

    use super::*;

    #[test]

    fn test() {
        struct M;

        impl Monoid for M {
            type T = i64;

            fn op(
                &self,
                l: Self::T,
                r: Self::T,
            ) -> Self::T {
                l + r
            }

            fn e(&self) -> Self::T {
                0
            }
        }

        let n = 5;

        let mut seg = DualSegtree::new(M {}, n);

        seg.operate(1, 3, 1);

        assert_eq!(seg.get(0), &0);

        assert_eq!(seg.get(1), &1);

        assert_eq!(seg.get(1), &1);

        assert_eq!(seg.get(0), &0);

        assert_eq!(seg.get(0), &0);

        *seg.get(0) = -1;

        seg.operate(0, 2, -1);

        assert_eq!(seg.get(0), &-2);

        assert_eq!(seg.get(1), &0);

        assert_eq!(seg.get(2), &1);
    }
}