[AcWing]798. 差分矩阵(算法基础课)(C++实现)二维差分模板题
1. 题目
2. 读题(需要重点注意的东西)
思路:
-------------------------------------------------解题思路-----------------------------------------------------------
类似于一维差分,多用于在某一个区间里做加法,能将O(n)的时间复杂度转换为O(1);
与一维差分完全一样,其主要区别在核心代码 insert中
上图来着于AcWing yxc,是对下方insert函数的图解。
void insert(int x1,int y1,int x2, int y2,int c){
b[x1][y1] += c;
b[x2+1][y1] -= c;
b[x1][y2+1] -= c;
b[x2+1][y2+1] += c;
}
-------------------------------------------------代码实现思路-----------------------------------------------------------
代码实现思路也类似于一维差分,结构也几乎一样,如果有疑问,可以下拉见 4. 可能有帮助的前置习题。
- 输入矩阵a
- 由a构造差分矩阵b
- q次插入
- 由b构造前缀和
- 输出b
此外注意,在步骤4中,是二维前缀和,如果有疑问,可以下拉见 4. 可能有帮助的前置习题。
// 4. 由b构造前缀和
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];
3. 解法
---------------------------------------------------解法---------------------------------------------------
#include<iostream>
using namespace std;
const int N = 1010;
int n,m,q;
int a[N][N],b[N][N];
// 核心函数
void insert(int x1,int y1,int x2, int y2,int c){
b[x1][y1] += c;
b[x2+1][y1] -= c;
b[x1][y2+1] -= c;
b[x2+1][y2+1] += c;
}
int main(){
cin >> n >> m >> q;
// 1. 输入矩阵a
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j++)
scanf("%d",&a[i][j]);
// 2. 由a构造差分矩阵b
for(int i = 1; i <= n;i++)
for(int j = 1; j <= m;j++)
insert(i,j,i,j,a[i][j]);
// 3. q次插入
while(q--){
int x1,y1,x2,y2,c;
cin >> x1 >> y1 >> x2 >> y2 >> c;
insert(x1,y1,x2,y2,c);
}
// 4. 由b构造前缀和
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];
// 5. 输出
for(int i = 1;i <= n; i++)
{
for(int j = 1;j <= m;j++)
printf("%d ",b[i][j]);
puts(" ");
}
return 0;
}
4. 可能有帮助的前置习题
5. 所用到的数据结构与算法思想
6. 总结
二维差分模板,主要应用于在 某一个区间内加上一个固定的值,该方法能将O(n)的时间复杂度降为O(1),推荐完全背下来。