算法题(133):二维差分
审题:
本题需要我们多次对某个矩形区域的数据加k,最后输出加完的数据思路:
方法一:二维差分本题涉及的是对二维的区间加同一个数的操作,且只显示一次最终结果,所以我们可以使用差分的方法
二维差分的性质:
1.和一维差分还原方法类似,二维差分的还原方法是从(1,1)开始求f[i][j]的前缀和
2.对某个位置的差分值加k:相当于对前缀和计算时包含该位置的数据索引位置都加了k
图示:图示为差分数组
由于最终还原数据的时候是对差分数组进行以(1,1)为左上角,(i,j)为右下角的矩阵的前缀和操作,所以如果这个求前缀和的矩阵包含了加k的索引数据,就表示(i,j)位置的数据加了k
3.进行二维差分修改和创建的方法
图示1:原二维数组
假设我们对图示的位置数据都加了k,相当于对以(2,3)为左上角,以(3.6)为右下角的矩阵集体进行加k操作
图示2:差分二维数组
首先我们对(2,3)加k,此时表示从(2,3)到(9,9)区域的数据都加了k
由于我们只能对红色区域加k,所以我们要消除(2,3)位置加k对其他位置的影响
第一步:在(2,7)位置-k,消除从(2,7)为左上角(9,9)为右下角的矩阵+k的影响
第二步:在(4,3)位置-k,消除从(4,3)为左上角(9,9)为右下角的矩阵+k的影响
第三步:由于(4,7)为左上角,(9,9)为右下角的矩阵经过两次-k,所以我们还需要加k来消除多减的k的影响
总结:
构建和修改操作:
x1,y1为左上角坐标,x2,y2为右下角坐标
f[x1][y1] += k;
f[x2 + 1][y1] -= k;
f[x1][y2 + 1] -= k;
f[x2 + 1][y2 + 1] += k;解题:
#include<iostream> using namespace std; typedef long long ll; const int N = 1010; int n, m, q; ll f[N][N];//差分数组 int main() {cin >> n >> m >> q;//预处理差分数组for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){ll num;cin >> num;f[i][j] += num;f[i + 1][j] -= num;f[i][j + 1] -= num;f[i + 1][j + 1] += num;}}//修改差分while (q--){ll x1, x2, y1, y2, k;cin >> x1 >> y1 >> x2 >> y2 >> k;f[x1][y1] += k;f[x2 + 1][y1] -= k;f[x1][y2 + 1] -= k;f[x2 + 1][y2 + 1] += k;}//还原数据for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + f[i][j];cout << f[i][j] << " ";}cout << endl;}return 0; }
第一步:构建差分数组
第二步:修改差分数组
第三步:还原每个位置的数据并输出
【模板】二维差分