insert
函数影响范围,在b差分数组这样操作影响到是a里面的,所以下图的矩阵表示的是a数组
b[x1][y1]+=c;会导致a
里面仅
绿色范围的a[i][j]+=c
b[x1][y2+1]-=c;会导致a
里面仅
黄色范围的a[i][j]-=c
b[x2+1][y1]-=c;会导致a
里面仅
蓝色范围的a[i][j]-=c
b[x2+1][y2+1]+=c;会导致a
里面仅
红色范围的a[i][j]+=c
这么操作差分数组b之后,会导致仅仅只有【x1】【y1】到【x2】【y2】对角线里面所有的元素a【i】【j】+=c,
黄色-=c和绿色的+=c扯平了,蓝色的部分-=c和绿色的+=c扯平了,红色的部分经过1次蓝色和黄色-=c,然后绿色和红色+=c扯平了,
然后经过这样操作,再对b差分数组求和(原理可参考acwing796-子矩阵的和-前缀和),就是得到了a[i][j]+=c
的数组了!
#include<iostream>
#define N 1086
using namespace std;
int n,m,q,a[N][N],b[N][N];
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)cin>>a[i][j];for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)insert(i,j,i,j,a[i][j]);for(int i=1;i<=q;++i){int x1,y1,x2,y2,c;cin>>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)b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];//对差分数组求元素和等于依次求出a[i][j]+c的值,类似求'子矩阵的和'for(int i=1;i<=n;++i){for(int j=1;j<=m;++j)cout<<b[i][j]<<" ";cout<<endl;}return 0;
}