主要内容如题,写博客为自己复习
二维差分的实现
#include<iostream>
using namespace std;
const int M=1e3+9;
int pre[M][M],a[M][M],d[M][M];
int main()
{
int n,m;cin>>n>>m;
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++)
d[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];//差分数组
}
二维差分的修改
原理
代码实现
#include<iostream>
using namespace std;
const int M=1e3+9;
int pre[M][M],a[M][M],d[M][M];
int main()
{
int n,m;cin>>n>>m;
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++)
d[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];//差分数组
int k;cin>>k;//记录修改次数
for(int i=1;i<=k;i++){//修改差分数组
int x1,x2,y1,y2,p;cin>>x1>>y1>>x2>>y2>>p;
d[x1][y1]+=p;d[x2+1][y2+1]+=p;
d[x1][y2+1]-=p;d[x2+1][y1]-=p;
}
//用前缀和还原a数组,方法是每一个点=我的左+我的上-我的左上+我自己
for(int i=1;i<=n;i++)
for(int j=1j<=m;j++)
a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+d[i][j];
}
由算点转化为格子
方法:每个左上角的点横纵坐标加1
#include<iostream>
using namespace std;
const int M=1e3+9;
int pre[M][M],a[M][M],d[M][M];
int main()
{
int n,m;cin>>n>>m;
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++)
d[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];//差分数组
int k;cin>>k;//记录修改次数
for(int i=1;i<=k;i++){//修改差分数组
int x1,x2,y1,y2,p;cin>>x1>>y1>>x2>>y2>>p;
d[x1+1][y1+1]+=p;d[x2+1][y2+1]+=p;
d[x1+1][y2+1]-=p;d[x2+1][y1+1]-=p;
}
//用前缀和还原a数组,方法是每一个点=我的左+我的上-我的左上+我自己
for(int i=1;i<=n;i++)
for(int j=1j<=m;j++)
a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+d[i][j];
}
这样算出来的a[i][j]就能代表格子了