competitive/data_structure/
range_ap_add.rs1#[derive(Debug, Clone)]
2pub struct RangeArithmeticProgressionAdd {
3 pub dd: Vec<i64>,
4}
5impl RangeArithmeticProgressionAdd {
6 pub fn new(n: usize) -> Self {
7 Self { dd: vec![0; n] }
8 }
9 pub fn update(&mut self, l: usize, k: usize, a: i64, d: i64) {
11 if let Some(e) = self.dd.get_mut(l) {
12 *e += a;
13 }
14 if let Some(e) = self.dd.get_mut(l + 1) {
15 *e += d - a;
16 }
17 if let Some(e) = self.dd.get_mut(l + k) {
18 *e += -a - k as i64 * d;
19 }
20 if let Some(e) = self.dd.get_mut(l + k + 1) {
21 *e += a + (k as i64 - 1) * d;
22 }
23 }
24 pub fn update_isize(&mut self, l: isize, k: usize, a: i64, d: i64) {
26 if l < 0 {
27 let r = l + k as isize;
28 if r > 0 {
29 self.update(0, r as usize, a - l as i64 * d, d);
30 }
31 } else {
32 self.update(l as usize, k, a, d);
33 }
34 }
35 pub fn build_inplace(&mut self) {
36 for _ in 0..2 {
37 for i in 0..self.dd.len() - 1 {
38 self.dd[i + 1] += self.dd[i];
39 }
40 }
41 }
42}
43
44#[test]
45fn test_range_ap_add() {
46 use crate::tools::{NotEmptySegment as Nes, Xorshift};
47 const N: usize = 1000;
48 const Q: usize = 10000;
49 const A: i64 = 1_000_000_000;
50 let mut rng = Xorshift::new();
51 let mut v = vec![0i64; N];
52 let mut ap = RangeArithmeticProgressionAdd::new(N);
53 for ((l, r), a, d) in rng.random_iter((Nes(N), -A..=A, -A..=A)).take(Q) {
54 for (i, v) in v[l..r].iter_mut().enumerate() {
55 *v += a + i as i64 * d;
56 }
57 ap.update(l, r - l, a, d);
58 }
59 ap.build_inplace();
60 assert_eq!(ap.dd, v);
61}