温故知新
前缀和矩阵的求和公式
今天学习到差分数组了,借机会复习一下前缀和矩阵求和的知识
图一: 求如图所示的面积和
s[i][j] = s[i][j-1] + s[i-1][j] - s[i-1][j-1] + a[i][j];
图二: 再演化一下,求给定上下端点的矩阵和
所给矩阵所有的和为
s = s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1];
差分矩阵在固定位置的insert
以 (x1,y1) 为左上角 , (x2,y2)为右下角,固定区间加上c
void insert(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;
}
有了上文这几样工具,实现差分矩阵的定区间修改也就不是什么难事了
具体代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int a[N][N],b[N][N];
int n,m,q;
void insert(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()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int x;
scanf("%d",&x);
insert(i,j,i,j,x);
}
while(q --)
{
int x1,y1,x2,y2,c;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
insert(x1,y1,x2,y2,c);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j] = a[i-1][j] + a[i][j-1] - a[i-1][j-1] + b[i][j];
//这里注释一下,很多小伙伴有问题,这里a数组其实就是b数组的前缀和
//其实就相当于先把输入的数据存入差分数组,然后利用差分数组实现所求数组
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
}