思路
差分是前缀和的逆运算
即对差分数组求一遍前缀和就可以得到原数组
其最主要的操作是: 将原数组中一个范围的数都加上(或减去)某个值,并且实现 的时间复杂度
实现为,在对应处b[i] + x
另外在 范围终点 b[r+1] - x
来保证之后的数不会加上这个x
本来需要每个原数组元素都加上 x 的操作,现在优化为只有两个数加上 x
实现
void insert(int l, int r, int x)
{
b[l] += x;
b[r+1] -= x;
}
差分矩阵
B数组的前缀和就是A数组
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e3 + 10;
int b[N][N];
int a[N][N];
void
insert(int l1, int r1, int l2, int r2, int c)
{
b[l1][r1] += c;
b[l1][r2 + 1] -= c;
b[l2 + 1][r1] -= c;
b[l2 + 1][r2 + 1] += c;
}
int
main()
{
int n, m, q, x, y, l, r, c;
cin >> n >> m >> q;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
cin >> a[i][j];
insert(i, j, i, j, a[i][j]);
}
}
while(q --)
{
cin >> x >> y >> l >> r >> c;
insert(x, y, l, r, 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][j] - b[i - 1][j - 1];
}
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
printf("%d ", b[i][j]);
puts("");
}
return 0;
}