1use std::ops::{Add, AddAssign, Mul, Neg, Sub};
10
11use crate::{algo::compressor::CompressorBuilder, ds::fenwick_add::*, num::one_zero::*};
12
13struct QAdd<T>(i64, usize, T);
14struct QSum<T>(i64, usize, T, usize);
15
16#[derive(Clone, Default)]
20pub struct StaticRectangleAddSum<T> {
21 add: Vec<(i64, i64, i64, i64, T)>,
22 sum: Vec<(i64, i64, i64, i64)>,
23}
24
25impl<T> StaticRectangleAddSum<T>
26where
27 T: Copy
28 + Mul<Output = T>
29 + Add<Output = T>
30 + Sub<Output = T>
31 + Neg<Output = T>
32 + AddAssign
33 + Zero
34 + One
35 + From<i64>,
36{
37 pub fn new() -> Self {
39 Self {
40 add: vec![],
41 sum: vec![],
42 }
43 }
44
45 pub fn query_add(&mut self, l: i64, d: i64, r: i64, u: i64, w: T) {
47 self.add.push((l, d, r, u, w));
48 }
49
50 pub fn query_sum(&mut self, l: i64, d: i64, r: i64, u: i64) {
52 self.sum.push((l, d, r, u));
53 }
54
55 pub fn solve(self) -> Vec<T> {
57 let mut cp = CompressorBuilder::new();
58 cp.extend(self.add.iter().flat_map(|(_, d, _, u, _)| vec![*d, *u]));
59 cp.extend(self.sum.iter().flat_map(|(_, d, _, u)| vec![*d, *u]));
60 let cp = cp.build();
61
62 let mut add = self
63 .add
64 .into_iter()
65 .flat_map(|(l, d, r, u, w)| {
66 let d = cp.index(&d);
67 let u = cp.index(&u);
68 vec![QAdd(l, d, w), QAdd(r, u, w), QAdd(l, u, -w), QAdd(r, d, -w)]
69 })
70 .collect::<Vec<_>>();
71
72 add.sort_by_key(|q| q.0);
73 add.reverse();
74
75 let mut sum = self
76 .sum
77 .iter()
78 .enumerate()
79 .flat_map(|(i, &(l, d, r, u))| {
80 let d = cp.index(&d);
81 let u = cp.index(&u);
82 vec![
83 QSum(l, d, T::one(), i),
84 QSum(r, u, T::one(), i),
85 QSum(l, u, -T::one(), i),
86 QSum(r, d, -T::one(), i),
87 ]
88 })
89 .collect::<Vec<_>>();
90
91 sum.sort_by_key(|q| q.0);
92 sum.reverse();
93
94 let mut fxy = FenwickTreeAdd::new(cp.size());
95 let mut fx = FenwickTreeAdd::new(cp.size());
96 let mut fy = FenwickTreeAdd::new(cp.size());
97 let mut f = FenwickTreeAdd::new(cp.size());
98 let mut ret = vec![T::zero(); self.sum.len()];
99
100 loop {
101 let is_sum = match (add.last(), sum.last()) {
102 (None, None) => break,
103 (Some(_), None) => false,
104 (None, Some(_)) => true,
105 (Some(a), Some(s)) => a.0 >= s.0,
106 };
107
108 if is_sum {
109 let QSum(r, y, c, index) = sum.pop().unwrap();
110 let u = *cp.get(y);
111
112 let ans = fxy.fold_to(..y)
113 + f.fold_to(..y) * r.into() * u.into()
114 + fy.fold_to(..y) * r.into()
115 + fx.fold_to(..y) * u.into();
116
117 ret[index] += c * ans;
118 } else {
119 let QAdd(l, y, w) = add.pop().unwrap();
120 let d = *cp.get(y);
121
122 fxy.add(y, w * l.into() * d.into());
123 f.add(y, w);
124 fy.sub(y, w * d.into());
125 fx.sub(y, w * l.into());
126 }
127 }
128
129 ret
130 }
131}