1use crate::num::{one_zero::Zero, traits::Signed};
3use std::ops::{Add, Range, Sub};
4
5pub struct Imos2D<T> {
7 data: Vec<Vec<T>>,
8 n: usize,
9 m: usize,
10}
11
12impl<T: Copy + Signed + Zero + Add<Output = T> + Sub<Output = T>> Imos2D<T> {
13 pub fn new(n: usize, m: usize) -> Self {
15 Self {
16 data: vec![vec![T::zero(); m]; n],
17 n,
18 m,
19 }
20 }
21
22 pub fn update(
24 &mut self,
25 Range { start: l, end: r }: Range<usize>,
26 Range { start: u, end: d }: Range<usize>,
27 value: T,
28 ) {
29 self.data[l][u] = self.data[l][u] + value;
30 if let Some(a) = self.data.get_mut(r) {
31 if let Some(x) = a.get_mut(d) {
32 *x = *x + value;
33 }
34 }
35
36 if let Some(x) = self.data[l].get_mut(d) {
37 *x = *x - value;
38 }
39 if let Some(a) = self.data.get_mut(r) {
40 a[u] = a[u] - value;
41 }
42 }
43
44 pub fn build(mut self) -> Vec<Vec<T>> {
46 for i in 1..self.n {
47 for j in 0..self.m {
48 self.data[i][j] = self.data[i][j] + self.data[i - 1][j];
49 }
50 }
51
52 for i in 0..self.n {
53 for j in 1..self.m {
54 self.data[i][j] = self.data[i][j] + self.data[i][j - 1];
55 }
56 }
57
58 self.data
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use my_testtools::*;
66 use rand::Rng;
67
68 #[test]
69 fn test() {
70 let n = 100;
71 let m = 200;
72 let t = 1000;
73
74 let mut rng = rand::thread_rng();
75
76 let mut a = Imos2D::<i32>::new(n, m);
77 let mut ans = vec![vec![0; m]; n];
78
79 for _ in 0..t {
80 let lr = rand_range(&mut rng, 0..n);
81 let ud = rand_range(&mut rng, 0..m);
82 let x = rng.gen_range(-100..=100);
83
84 a.update(lr.clone(), ud.clone(), x);
85
86 for i in lr {
87 for j in ud.clone() {
88 ans[i][j] += x;
89 }
90 }
91 }
92
93 assert_eq!(a.build(), ans);
94 }
95}