haar_lib/ds/
dual_segtree.rs1#![allow(clippy::wrong_self_convention)]
3
4pub use crate::algebra::traits::Monoid;
5use crate::misc::range::range_bounds_to_range;
6use std::cell::RefCell;
7use std::ops::RangeBounds;
8
9#[derive(Clone)]
11pub struct DualSegtree<M: Monoid> {
12 original_size: usize,
13 size: usize,
14 data: RefCell<Vec<M>>,
15}
16
17impl<M: Monoid + Clone> DualSegtree<M> {
18 pub fn new(n: usize) -> Self {
20 let size = n.next_power_of_two() * 2;
21 let data = RefCell::new(vec![M::id(); size]);
22 DualSegtree {
23 original_size: n,
24 size,
25 data,
26 }
27 }
28
29 pub fn from_vec(a: Vec<M>) -> Self {
33 let size = a.len().next_power_of_two() * 2;
34 let original_size = a.len();
35 let mut data = vec![M::id(); size];
36 for (i, e) in a.into_iter().enumerate() {
37 data[i + size / 2] = e.clone();
38 }
39 DualSegtree {
40 original_size,
41 size,
42 data: RefCell::new(data),
43 }
44 }
45
46 fn propagate(&self, i: usize) {
47 let mut data = self.data.borrow_mut();
48
49 if i < self.size / 2 {
50 data[i << 1] = M::op(data[i << 1].clone(), data[i].clone());
51 data[(i << 1) | 1] = M::op(data[(i << 1) | 1].clone(), data[i].clone());
52 data[i] = M::id();
53 }
54 }
55
56 fn propagate_top_down(&self, mut i: usize) {
57 let mut temp = vec![];
58 while i > 1 {
59 i >>= 1;
60 temp.push(i);
61 }
62
63 for &i in temp.iter().rev() {
64 self.propagate(i);
65 }
66 }
67
68 pub fn get(&self, i: usize) -> M {
70 self.propagate_top_down(i + self.size / 2);
71 self.data.borrow()[i + self.size / 2].clone()
72 }
73
74 pub fn to_vec(&self) -> Vec<M> {
76 for i in 1..self.size {
77 self.propagate(i);
78 }
79
80 self.data.borrow()[self.size / 2..self.size / 2 + self.original_size].to_vec()
81 }
82
83 pub fn update(&mut self, range: impl RangeBounds<usize>, value: M) {
85 let (l, r) = range_bounds_to_range(range, 0, self.original_size);
86
87 let mut l = l + self.size / 2;
88 let mut r = r + self.size / 2;
89
90 self.propagate_top_down(l);
91 self.propagate_top_down(r);
92
93 let mut data = self.data.borrow_mut();
94
95 while l < r {
96 if (r & 1) == 1 {
97 r -= 1;
98 data[r] = M::op(data[r].clone(), value.clone());
99 }
100 if (l & 1) == 1 {
101 data[l] = M::op(data[l].clone(), value.clone());
102 l += 1;
103 }
104 l >>= 1;
105 r >>= 1;
106 }
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use crate::algebra::sum::*;
114 use my_testtools::*;
115 use rand::Rng;
116
117 #[test]
118 fn test() {
119 let mut rng = rand::thread_rng();
120 let n = 100;
121
122 let mut a = (0..n)
123 .map(|_| {
124 let x = rng.gen_range(0..10000);
125 Sum(x)
126 })
127 .collect::<Vec<_>>();
128 let mut seg = DualSegtree::<Sum<u32>>::from_vec(a.clone());
129
130 for _ in 0..100 {
131 let lr = rand_range(&mut rng, 0..n);
132 let x = rng.gen_range(0..10000);
133
134 seg.update(lr.clone(), Sum(x));
135 a[lr].iter_mut().for_each(|e| e.op_assign_r(Sum(x)));
136
137 assert_eq!(a, seg.to_vec());
138 }
139 }
140}