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