1 solutions
-
0
算法分析
数组是数组的前缀和数组,那么是的差分数组
原数组:
我们去构造差分数组:
使得数组中是数组左上角到右下角所包围矩形元素的和。
如何构造数组呢?
我们去逆向思考。
同一维差分,我们构造二维差分数组目的是为了 让原二维数组中所选中子矩阵中的每一个元素加上的操作,可以由的时间复杂度优化成
已知原数组中被选中的子矩阵为 以为左上角,以为右下角所围成的矩形区域;
始终要记得,数组是数组的前缀和数组,比如对数组的的修改,会影响到数组中从及往后的每一个数。
假定我们已经构造好了数组,类比一维差分,我们执行以下操作 来使被选中的子矩阵中的每个元素的值加上c
每次对数组执行以上操作,等价于:
for(int i=x1;i<=x2;i++) for(int j=y1;j<=y2;j++) a[i][j]+=c;
我们画个图去理解一下这个过程:
; 让整个数组中蓝色矩形面积的元素都加上了。
; 让整个数组中绿色矩形面积的元素再减去,使其内元素不发生改变。
; 让整个数组中紫色矩形面积的元素再减去,使其内元素不发生改变。
;让整个数组中红色矩形面积的元素再加上,红色内的相当于被减了两次,再加上一次,才能使其恢复。
代码实现
#include<bits/stdc++.h> using namespace std; const int N=1010; int 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() { int n,m,q; cin>>n>>m>>q; for(int i=1;i<=n;i++) //通过原数组构造差分数组 { for(int j=1;j<=m;j++) { int x; cin>>x; insert(i,j,i,j,x); } } while(q--) //进行差分操作 { 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++) { a[i][j]=a[i][j-1]+a[i-1][j]-a[i-1][j-1]+b[i][j]; } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cout<<a[i][j]<<" "; } cout<<endl; } return 0; }
- 1
Information
- ID
- 342
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 6
- Tags
- # Submissions
- 3
- Accepted
- 2
- Uploaded By