1use crate::algebra::{act::Act, traits::*};
3use crate::misc::range::range_bounds_to_range;
4use std::ops::RangeBounds;
5
6pub struct LazySegtree<M: Monoid, A: Act<M>> {
8 monoid: M,
9 act: A,
10 size: usize,
11 original_size: usize,
12 data: Vec<M::Element>,
13 lazy: Vec<A::Element>,
14}
15
16impl<M, A> LazySegtree<M, A>
17where
18 M: Monoid,
19 A: Act<M>,
20 M::Element: Clone,
21 A::Element: Clone + PartialEq,
22{
23 pub fn new(monoid: M, act: A, n: usize) -> Self {
25 let size = n.next_power_of_two() * 2;
26 Self {
27 size,
28 original_size: n,
29 data: vec![monoid.id(); size],
30 lazy: vec![act.monoid().id(); size],
31 monoid,
32 act,
33 }
34 }
35
36 pub fn from_vec(monoid: M, act: A, s: Vec<M::Element>) -> Self {
40 let n = s.len();
41 let size = n.next_power_of_two() * 2;
42 let mut this = Self {
43 size,
44 original_size: n,
45 data: vec![monoid.id(); size],
46 lazy: vec![act.id(); size],
47 monoid,
48 act,
49 };
50
51 for (i, x) in s.into_iter().enumerate() {
52 this.data[size / 2 + i] = x;
53 }
54
55 for i in (1..size / 2).rev() {
56 this.data[i] = this
57 .monoid
58 .op(this.data[i << 1].clone(), this.data[(i << 1) | 1].clone());
59 }
60
61 this
62 }
63
64 pub fn to_slice(&mut self) -> &[M::Element] {
68 for i in 1..self.size {
69 self.propagate(i);
70 }
71
72 &self.data[self.size / 2..self.size / 2 + self.original_size]
73 }
74
75 fn propagate(&mut self, i: usize) {
76 if self.lazy[i] == self.act.id() {
77 return;
78 }
79 if i < self.size / 2 {
80 let l = i << 1;
81 let r = (i << 1) | 1;
82
83 self.lazy[l] = self.act.op(self.lazy[l].clone(), self.lazy[i].clone());
84 self.lazy[r] = self.act.op(self.lazy[r].clone(), self.lazy[i].clone());
85 }
86 let len = (self.size / 2) >> (31 - (i as u32).leading_zeros());
87 self.data[i] = self.act.act(
88 &self.monoid,
89 self.data[i].clone(),
90 self.lazy[i].clone(),
91 len,
92 );
93 self.lazy[i] = self.act.id();
94 }
95
96 fn propagate_top_down(&mut self, mut i: usize) {
97 let mut temp = vec![i];
98 while i > 1 {
99 i >>= 1;
100 temp.push(i);
101 }
102
103 for i in temp.into_iter().rev() {
104 self.propagate(i);
105 }
106 }
107
108 fn bottom_up(&mut self, mut i: usize) {
109 while i > 1 {
110 i >>= 1;
111 self.propagate(i << 1);
112 self.propagate((i << 1) | 1);
113 self.data[i] = self
114 .monoid
115 .op(self.data[i << 1].clone(), self.data[(i << 1) | 1].clone());
116 }
117 }
118
119 pub fn get(&mut self, i: usize) -> M::Element {
121 self.propagate_top_down(i + self.size / 2);
122 self.data[i + self.size / 2].clone()
123 }
124
125 pub fn fold(&mut self, range: impl RangeBounds<usize>) -> M::Element {
127 let (l, r) = range_bounds_to_range(range, 0, self.original_size);
128
129 self.propagate_top_down(l + self.size / 2);
130 if r < self.size / 2 {
131 self.propagate_top_down(r + self.size / 2);
132 }
133
134 let mut ret_l = self.monoid.id();
135 let mut ret_r = self.monoid.id();
136
137 let mut l = l + self.size / 2;
138 let mut r = r + self.size / 2;
139
140 while l < r {
141 if r & 1 == 1 {
142 r -= 1;
143 self.propagate(r);
144 ret_r = self.monoid.op(self.data[r].clone(), ret_r.clone());
145 }
146 if l & 1 == 1 {
147 self.propagate(l);
148 ret_l = self.monoid.op(ret_l.clone(), self.data[l].clone());
149 l += 1;
150 }
151 r >>= 1;
152 l >>= 1;
153 }
154
155 self.monoid.op(ret_l, ret_r)
156 }
157
158 pub fn assign(&mut self, i: usize, value: M::Element) {
160 self.propagate_top_down(i + self.size / 2);
161 self.data[i + self.size / 2] = value;
162 self.bottom_up(i + self.size / 2);
163 }
164
165 pub fn update(&mut self, range: impl RangeBounds<usize>, x: A::Element) {
167 let (l, r) = range_bounds_to_range(range, 0, self.original_size);
168
169 self.propagate_top_down(l + self.size / 2);
170 if r < self.size / 2 {
171 self.propagate_top_down(r + self.size / 2);
172 }
173
174 {
175 let mut l = l + self.size / 2;
176 let mut r = r + self.size / 2;
177
178 while l < r {
179 if r & 1 == 1 {
180 r -= 1;
181 self.lazy[r] = self.act.op(self.lazy[r].clone(), x.clone());
182 }
183 if l & 1 == 1 {
184 self.lazy[l] = self.act.op(self.lazy[l].clone(), x.clone());
185 l += 1;
186 }
187 r >>= 1;
188 l >>= 1;
189 }
190 }
191
192 self.bottom_up(l + self.size / 2);
193 if r < self.size / 2 {
194 self.bottom_up(r + self.size / 2);
195 }
196 }
197}
198
199#[cfg(test)]
200mod tests {
201 use super::*;
202 use my_testtools::*;
203 use rand::Rng;
204
205 fn test<M, A, F>(n: usize, q: usize, monoid: M, act: A, mut gen: F)
206 where
207 M: Monoid<Element: Copy + PartialEq + std::fmt::Debug> + Clone,
208 A: Act<M, Element: Copy + PartialEq> + Clone,
209 F: FnMut() -> A::Element,
210 {
211 let mut seg = LazySegtree::new(monoid.clone(), act.clone(), n);
212 let mut vec = vec![monoid.id(); n];
213
214 let mut rng = rand::thread_rng();
215
216 for _ in 0..q {
217 let lr = rand_range(&mut rng, 0..n);
218
219 match rng.gen::<u32>() % 2 {
220 0 => {
221 let x = gen();
222
223 seg.update(lr.clone(), x);
224 vec[lr]
225 .iter_mut()
226 .for_each(|y| *y = act.act_one(&monoid, *y, x));
227 }
228 1 => {
229 assert_eq!(
230 seg.fold(lr.clone()),
231 vec[lr].iter().cloned().fold_m(&monoid)
232 );
233 }
234 _ => unreachable!(),
235 }
236 }
237 }
238
239 use crate::algebra;
240
241 #[test]
242 fn add_sum() {
243 let mut rng = rand::thread_rng();
244 let m = algebra::sum::Sum::<u64>::new();
245 test(100, 100, m, algebra::act::add_sum::AddSum(m), || {
246 rng.gen_range(0..1000)
247 });
248 }
249
250 #[test]
251 fn chmax_max() {
252 let mut rng = rand::thread_rng();
253 let m = algebra::min_max::Max::<i64>::new();
254 test(100, 100, m, algebra::act::chmax_max::ChmaxMax(m), || {
255 rng.gen_range(-1000..1000)
256 });
257 }
258
259 #[test]
260 fn chmin_min() {
261 let mut rng = rand::thread_rng();
262 let m = algebra::min_max::Min::<i64>::new();
263 test(100, 100, m, algebra::act::chmin_min::ChminMin(m), || {
264 rng.gen_range(-1000..1000)
265 });
266 }
267}