ac_library/
lazysegtree.rs

1use crate::internal_bit::ceil_pow2;
2use crate::Monoid;
3
4pub trait MapMonoid {
5    type M: Monoid;
6    type F: Clone;
7    // type S = <Self::M as Monoid>::S;
8    fn identity_element() -> <Self::M as Monoid>::S {
9        Self::M::identity()
10    }
11    fn binary_operation(
12        a: &<Self::M as Monoid>::S,
13        b: &<Self::M as Monoid>::S,
14    ) -> <Self::M as Monoid>::S {
15        Self::M::binary_operation(a, b)
16    }
17    fn identity_map() -> Self::F;
18    fn mapping(f: &Self::F, x: &<Self::M as Monoid>::S) -> <Self::M as Monoid>::S;
19    fn composition(f: &Self::F, g: &Self::F) -> Self::F;
20}
21
22impl<F: MapMonoid> Default for LazySegtree<F> {
23    fn default() -> Self {
24        Self::new(0)
25    }
26}
27impl<F: MapMonoid> LazySegtree<F> {
28    pub fn new(n: usize) -> Self {
29        vec![F::identity_element(); n].into()
30    }
31}
32impl<F: MapMonoid> From<Vec<<F::M as Monoid>::S>> for LazySegtree<F> {
33    fn from(v: Vec<<F::M as Monoid>::S>) -> Self {
34        let n = v.len();
35        let log = ceil_pow2(n as u32) as usize;
36        let size = 1 << log;
37        let mut d = vec![F::identity_element(); 2 * size];
38        let lz = vec![F::identity_map(); size];
39        d[size..(size + n)].clone_from_slice(&v);
40        let mut ret = LazySegtree {
41            n,
42            size,
43            log,
44            d,
45            lz,
46        };
47        for i in (1..size).rev() {
48            ret.update(i);
49        }
50        ret
51    }
52}
53
54impl<F: MapMonoid> LazySegtree<F> {
55    pub fn set(&mut self, mut p: usize, x: <F::M as Monoid>::S) {
56        assert!(p < self.n);
57        p += self.size;
58        for i in (1..=self.log).rev() {
59            self.push(p >> i);
60        }
61        self.d[p] = x;
62        for i in 1..=self.log {
63            self.update(p >> i);
64        }
65    }
66
67    pub fn get(&mut self, mut p: usize) -> <F::M as Monoid>::S {
68        assert!(p < self.n);
69        p += self.size;
70        for i in (1..=self.log).rev() {
71            self.push(p >> i);
72        }
73        self.d[p].clone()
74    }
75
76    pub fn prod<R>(&mut self, range: R) -> <F::M as Monoid>::S
77    where
78        R: RangeBounds<usize>,
79    {
80        // Trivial optimization
81        if range.start_bound() == Bound::Unbounded && range.end_bound() == Bound::Unbounded {
82            return self.all_prod();
83        }
84
85        let mut r = match range.end_bound() {
86            Bound::Included(r) => r + 1,
87            Bound::Excluded(r) => *r,
88            Bound::Unbounded => self.n,
89        };
90        let mut l = match range.start_bound() {
91            Bound::Included(l) => *l,
92            Bound::Excluded(l) => l + 1,
93            // TODO: There are another way of optimizing [0..r)
94            Bound::Unbounded => 0,
95        };
96
97        assert!(l <= r && r <= self.n);
98        if l == r {
99            return F::identity_element();
100        }
101
102        l += self.size;
103        r += self.size;
104
105        for i in (1..=self.log).rev() {
106            if ((l >> i) << i) != l {
107                self.push(l >> i);
108            }
109            if ((r >> i) << i) != r {
110                self.push(r >> i);
111            }
112        }
113
114        let mut sml = F::identity_element();
115        let mut smr = F::identity_element();
116        while l < r {
117            if l & 1 != 0 {
118                sml = F::binary_operation(&sml, &self.d[l]);
119                l += 1;
120            }
121            if r & 1 != 0 {
122                r -= 1;
123                smr = F::binary_operation(&self.d[r], &smr);
124            }
125            l >>= 1;
126            r >>= 1;
127        }
128
129        F::binary_operation(&sml, &smr)
130    }
131
132    pub fn all_prod(&self) -> <F::M as Monoid>::S {
133        self.d[1].clone()
134    }
135
136    pub fn apply(&mut self, mut p: usize, f: F::F) {
137        assert!(p < self.n);
138        p += self.size;
139        for i in (1..=self.log).rev() {
140            self.push(p >> i);
141        }
142        self.d[p] = F::mapping(&f, &self.d[p]);
143        for i in 1..=self.log {
144            self.update(p >> i);
145        }
146    }
147    pub fn apply_range<R>(&mut self, range: R, f: F::F)
148    where
149        R: RangeBounds<usize>,
150    {
151        let mut r = match range.end_bound() {
152            Bound::Included(r) => r + 1,
153            Bound::Excluded(r) => *r,
154            Bound::Unbounded => self.n,
155        };
156        let mut l = match range.start_bound() {
157            Bound::Included(l) => *l,
158            Bound::Excluded(l) => l + 1,
159            // TODO: There are another way of optimizing [0..r)
160            Bound::Unbounded => 0,
161        };
162
163        assert!(l <= r && r <= self.n);
164        if l == r {
165            return;
166        }
167
168        l += self.size;
169        r += self.size;
170
171        for i in (1..=self.log).rev() {
172            if ((l >> i) << i) != l {
173                self.push(l >> i);
174            }
175            if ((r >> i) << i) != r {
176                self.push((r - 1) >> i);
177            }
178        }
179
180        {
181            let l2 = l;
182            let r2 = r;
183            while l < r {
184                if l & 1 != 0 {
185                    self.all_apply(l, f.clone());
186                    l += 1;
187                }
188                if r & 1 != 0 {
189                    r -= 1;
190                    self.all_apply(r, f.clone());
191                }
192                l >>= 1;
193                r >>= 1;
194            }
195            l = l2;
196            r = r2;
197        }
198
199        for i in 1..=self.log {
200            if ((l >> i) << i) != l {
201                self.update(l >> i);
202            }
203            if ((r >> i) << i) != r {
204                self.update((r - 1) >> i);
205            }
206        }
207    }
208
209    pub fn max_right<G>(&mut self, mut l: usize, g: G) -> usize
210    where
211        G: Fn(<F::M as Monoid>::S) -> bool,
212    {
213        assert!(l <= self.n);
214        assert!(g(F::identity_element()));
215        if l == self.n {
216            return self.n;
217        }
218        l += self.size;
219        for i in (1..=self.log).rev() {
220            self.push(l >> i);
221        }
222        let mut sm = F::identity_element();
223        while {
224            // do
225            while l % 2 == 0 {
226                l >>= 1;
227            }
228            if !g(F::binary_operation(&sm, &self.d[l])) {
229                while l < self.size {
230                    self.push(l);
231                    l *= 2;
232                    let res = F::binary_operation(&sm, &self.d[l]);
233                    if g(res.clone()) {
234                        sm = res;
235                        l += 1;
236                    }
237                }
238                return l - self.size;
239            }
240            sm = F::binary_operation(&sm, &self.d[l]);
241            l += 1;
242            //while
243            {
244                let l = l as isize;
245                (l & -l) != l
246            }
247        } {}
248        self.n
249    }
250
251    pub fn min_left<G>(&mut self, mut r: usize, g: G) -> usize
252    where
253        G: Fn(<F::M as Monoid>::S) -> bool,
254    {
255        assert!(r <= self.n);
256        assert!(g(F::identity_element()));
257        if r == 0 {
258            return 0;
259        }
260        r += self.size;
261        for i in (1..=self.log).rev() {
262            self.push((r - 1) >> i);
263        }
264        let mut sm = F::identity_element();
265        while {
266            // do
267            r -= 1;
268            while r > 1 && r % 2 != 0 {
269                r >>= 1;
270            }
271            if !g(F::binary_operation(&self.d[r], &sm)) {
272                while r < self.size {
273                    self.push(r);
274                    r = 2 * r + 1;
275                    let res = F::binary_operation(&self.d[r], &sm);
276                    if g(res.clone()) {
277                        sm = res;
278                        r -= 1;
279                    }
280                }
281                return r + 1 - self.size;
282            }
283            sm = F::binary_operation(&self.d[r], &sm);
284            // while
285            {
286                let r = r as isize;
287                (r & -r) != r
288            }
289        } {}
290        0
291    }
292}
293
294#[derive(Clone)]
295pub struct LazySegtree<F>
296where
297    F: MapMonoid,
298{
299    n: usize,
300    size: usize,
301    log: usize,
302    d: Vec<<F::M as Monoid>::S>,
303    lz: Vec<F::F>,
304}
305impl<F> LazySegtree<F>
306where
307    F: MapMonoid,
308{
309    fn update(&mut self, k: usize) {
310        self.d[k] = F::binary_operation(&self.d[2 * k], &self.d[2 * k + 1]);
311    }
312    fn all_apply(&mut self, k: usize, f: F::F) {
313        self.d[k] = F::mapping(&f, &self.d[k]);
314        if k < self.size {
315            self.lz[k] = F::composition(&f, &self.lz[k]);
316        }
317    }
318    fn push(&mut self, k: usize) {
319        self.all_apply(2 * k, self.lz[k].clone());
320        self.all_apply(2 * k + 1, self.lz[k].clone());
321        self.lz[k] = F::identity_map();
322    }
323}
324
325// TODO is it useful?
326use std::{
327    fmt::{Debug, Error, Formatter, Write},
328    ops::{Bound, RangeBounds},
329};
330impl<F> Debug for LazySegtree<F>
331where
332    F: MapMonoid,
333    F::F: Debug,
334    <F::M as Monoid>::S: Debug,
335{
336    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
337        for i in 0..self.log {
338            for j in 0..1 << i {
339                f.write_fmt(format_args!(
340                    "{:?}[{:?}]\t",
341                    self.d[(1 << i) + j],
342                    self.lz[(1 << i) + j]
343                ))?;
344            }
345            f.write_char('\n')?;
346        }
347        for i in 0..self.size {
348            f.write_fmt(format_args!("{:?}\t", self.d[self.size + i]))?;
349        }
350        Ok(())
351    }
352}
353
354#[cfg(test)]
355mod tests {
356    use std::ops::{Bound::*, RangeBounds};
357
358    use crate::{LazySegtree, MapMonoid, Max};
359
360    struct MaxAdd;
361    impl MapMonoid for MaxAdd {
362        type M = Max<i32>;
363        type F = i32;
364
365        fn identity_map() -> Self::F {
366            0
367        }
368
369        fn mapping(&f: &i32, &x: &i32) -> i32 {
370            f + x
371        }
372
373        fn composition(&f: &i32, &g: &i32) -> i32 {
374            f + g
375        }
376    }
377
378    #[test]
379    fn test_max_add_lazy_segtree() {
380        let base = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
381        let n = base.len();
382        let mut segtree: LazySegtree<MaxAdd> = base.clone().into();
383        check_segtree(&base, &mut segtree);
384
385        let mut segtree = LazySegtree::<MaxAdd>::new(n);
386        let mut internal = vec![i32::MIN; n];
387        for i in 0..n {
388            segtree.set(i, base[i]);
389            internal[i] = base[i];
390            check_segtree(&internal, &mut segtree);
391        }
392
393        segtree.set(6, 5);
394        internal[6] = 5;
395        check_segtree(&internal, &mut segtree);
396
397        segtree.apply(5, 1);
398        internal[5] += 1;
399        check_segtree(&internal, &mut segtree);
400
401        segtree.set(6, 0);
402        internal[6] = 0;
403        check_segtree(&internal, &mut segtree);
404
405        segtree.apply_range(3..8, 2);
406        internal[3..8].iter_mut().for_each(|e| *e += 2);
407        check_segtree(&internal, &mut segtree);
408
409        segtree.apply_range(2..=5, 7);
410        internal[2..=5].iter_mut().for_each(|e| *e += 7);
411        check_segtree(&internal, &mut segtree);
412    }
413
414    //noinspection DuplicatedCode
415    fn check_segtree(base: &[i32], segtree: &mut LazySegtree<MaxAdd>) {
416        let n = base.len();
417        #[allow(clippy::needless_range_loop)]
418        for i in 0..n {
419            assert_eq!(segtree.get(i), base[i]);
420        }
421
422        check(base, segtree, ..);
423        for i in 0..=n {
424            check(base, segtree, ..i);
425            check(base, segtree, i..);
426            if i < n {
427                check(base, segtree, ..=i);
428            }
429            for j in i..=n {
430                check(base, segtree, i..j);
431                if j < n {
432                    check(base, segtree, i..=j);
433                    check(base, segtree, (Excluded(i), Included(j)));
434                }
435            }
436        }
437        assert_eq!(
438            segtree.all_prod(),
439            base.iter().max().copied().unwrap_or(i32::MIN)
440        );
441        for k in 0..=10 {
442            let f = |x| x < k;
443            for i in 0..=n {
444                assert_eq!(
445                    Some(segtree.max_right(i, f)),
446                    (i..=n)
447                        .filter(|&j| f(base[i..j].iter().max().copied().unwrap_or(i32::MIN)))
448                        .max()
449                );
450            }
451            for j in 0..=n {
452                assert_eq!(
453                    Some(segtree.min_left(j, f)),
454                    (0..=j)
455                        .filter(|&i| f(base[i..j].iter().max().copied().unwrap_or(i32::MIN)))
456                        .min()
457                );
458            }
459        }
460    }
461
462    fn check(base: &[i32], segtree: &mut LazySegtree<MaxAdd>, range: impl RangeBounds<usize>) {
463        let expected = base
464            .iter()
465            .enumerate()
466            .filter_map(|(i, a)| Some(a).filter(|_| range.contains(&i)))
467            .max()
468            .copied()
469            .unwrap_or(i32::MIN);
470        assert_eq!(segtree.prod(range), expected);
471    }
472}