目录
一、题目描述:
二、整体思路:
(一):差分矩阵模板:
首先要知道由于一维数组时,。所以二维数组时。也就是以为左上角,为右下角的矩阵的元素之和。
另外根据差分数组性质,会使得。
因此,对于以为左上角,为右下角的矩阵,对其中所有
进行操作,就意味着要对进行操作,
但是这样会令与
同时增加,所以和必须要减去。最后要加回减多的部分即。矩阵图示如下:
1,1 | ||||||||
x1,y1 | x1,y2+1 | |||||||
...... | ||||||||
x2,y2 | ||||||||
x2+1,y1 | x2+1,y2+1 | |||||||
n,m |
//对应的差分矩阵操作为
int q;
while(q--){
int x1,y1,x2,y2,c;cin>>x1>>y1>>x2>>y2>>c;
diff[x1][y1]+=c;
diff[x1][y2+1]-=c;
diff[x2+1][y1]-=c;
diff[x2+1][y2+1]+=c;
}
1,1 | ||||||||
i-1,j | ||||||||
i,j | ||||||||
n,m |
1,1 | ||||||||
i,j-1 | i,j | |||||||
n,m |
1,1 | ||||||||
i-1,j-1 | ||||||||
i,j | ||||||||
n,m |
//初始化差分矩阵,最后更新arr[][]时也是用这条式子稍作变形
diff[i][j]=arr[i][j]+arr[i-1][j-1]-arr[i][j-1]-arr[i-1][j];
(二):逐行用一维差分数组更新arr[][]:
遍历每一行,只需要在diff[][]的每一行的y1处加上c,每一行的y2+1处减去c。按照一维差分数组的方法去做。
三、代码:
#方法一
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,q;cin>>n>>m>>q;
int arr[n+10][m+10];
int diff[n+10][m+10];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>arr[i][j];
diff[i][j]=arr[i][j]+arr[i-1][j-1]-arr[i][j-1]-arr[i-1][j];
}//arr[][]和diff[][]是可以通过累加公式互相转换的!
}
while(q--){
int x1,y1,x2,y2,c;cin>>x1>>y1>>x2>>y2>>c;
diff[x1][y1]+=c;//如整体思路(一)
diff[x1][y2+1]-=c;
diff[x2+1][y1]-=c;
diff[x2+1][y2+1]+=c;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
arr[i][j]=arr[i][j-1]+arr[i-1][j]-arr[i-1][j-1]+diff[i][j];//利用上面公式变形
cout<<arr[i][j]<<" ";
}
cout<<'\n';
}
return 0;
}
//方法二
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,q;cin>>n>>m>>q;
int arr[n+10][m+10];
int diff[n+10][m+10];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>arr[i][j];
diff[i][j]=arr[i][j]-arr[i][j-1];//初始化差分矩阵,按行初始化一维差分数组
}
}
while(q--){
int x1,y1,x2,y2,c;cin>>x1>>y1>>x2>>y2>>c;
for(int i=x1;i<=x2;i++){
diff[i][y1]+=c;//按照一维差分数组的模板做,多了遍历每一行而已
diff[i][y2+1]-=c;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
arr[i][j]=arr[i][j-1]+diff[i][j];
cout<<arr[i][j]<<" ";
}
cout<<'\n';
}
return 0;
}