构造
b
[
i
,
j
]
b[i, j]
b[i,j]使得矩阵左上角(包括自身)所有的b的和等于
a
[
i
,
j
]
a[i, j]
a[i,j]。
例如
b
[
1
,
1
]
+
b
[
1
,
2
]
+
b
[
1
,
3
]
+
b
[
2
,
1
]
+
b
[
2
,
2
]
+
b
[
2
,
3
]
=
a
[
2
,
3
]
b[1, 1] + b[1, 2] + b[1, 3] + b[2, 1] + b[2, 2] + b[2, 3] = a[2, 3]
b[1,1]+b[1,2]+b[1,3]+b[2,1]+b[2,2]+b[2,3]=a[2,3]
我们知道,令
b
[
i
,
j
]
+
c
b[i, j] + c
b[i,j]+c,求前缀和后,相当于对
a
[
i
,
j
]
a[i, j]
a[i,j]和它右下角所有的
a
a
a都加上
c
c
c。
因此若想只对
[
x
1
,
y
1
]
,
[
x
2
,
y
2
]
[x_1, y_1], [x_2, y_2]
[x1,y1],[x2,y2]矩阵内的
a
a
a加
c
c
c,需要先在
b
[
x
1
,
y
1
]
+
c
b[x_1, y_1] + c
b[x1,y1]+c,再
b
[
x
1
,
y
2
+
1
]
−
c
,
b
[
x
2
+
1
,
y
1
]
−
c
b[x_1, y_2+1]-c, b[x_2+1, y_1]-c
b[x1,y2+1]−c,b[x2+1,y1]−c,最后
b
[
x
2
+
1
,
y
2
+
1
]
+
c
b[x_2+1, y_2+1] + c
b[x2+1,y2+1]+c
至于b数组的初始化,完全可以复用对a矩阵+c的过程,只需令
[
x
1
,
y
1
]
,
[
x
2
,
y
2
]
[x_1, y_1], [x_2, y_2]
[x1,y1],[x2,y2]的矩阵变成
[
i
,
j
]
,
[
i
,
j
]
[i, j], [i, j]
[i,j],[i,j]大小为1的矩阵即可。
#include <iostream>
using namespace std;
int n, m, q;
int b[1005][1005];
void add(int x1, int y1, int x2, int y2, int c) {
b[x1][y1] += c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y1] -= c;
b[x2 + 1][y2 + 1] += c;
}
int main() {
int a;
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i <= n; i ++ ) {
for (int j = 1; j <= m; j ++ ) {
scanf("%d", &a);
add(i, j, i, j, a);
}
}
int x1, y1, x2, y2, c;
for (int i = 1; i <= q; i ++ ) {
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &c);
add(x1, y1, x2, y2, c);
}
for (int i = 1; i <= n; i ++ ) {
for (int j = 1; j <= m; j ++ ) {
b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
printf("%d ", b[i][j]);
}
printf("\n");
}
return 0;
}