二维前缀和
// #include<stdio.h> #include<bits/stdc++.h> using namespace std; #define maxnn 2000 long long mapp[maxnn][maxnn]; int yyy=0; int n,m; int q; int main() { cin>>n>>m; int x1,y1,x2,y2; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d",&yyy); mapp[i][j]=mapp[i][j-1]+mapp[i-1][j]-mapp[i-1][j-1]+yyy; } } scanf("%d",&q); while(q--) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("%lld ",mapp[x2][y2]-mapp[x1-1][y2]-mapp[x2][y1-1]+mapp[x1-1][y1-1]); } }
二维差分
// #include<stdio.h> #include<bits/stdc++.h> using namespace std; int n,m; #define maxnn 2000 long long sum[maxnn][maxnn]; long long a[maxnn][maxnn]; long long mapp[maxnn][maxnn]; long long d[maxnn][maxnn]; int main() { int x,y; int p,q; cin>>n>>m; int x1,y1,x2,y2,k; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) { scanf("%lld",&a[i][j]); } } cin>>p>>q; while(p--) { scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&k); d[x1][y1]+=k; //d[i][j]表示以(i,j)为左上角的差分值 前缀和就是该点的增量 d[x1][y2+1]-=k; d[x2+1][y1]-=k; d[x2+1][y2+1]+=k; } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+d[i][j];//前缀和 a[i][j]+=sum[i][j]; 加上增量 mapp[i][j]=mapp[i-1][j]+mapp[i][j-1]-mapp[i-1][j-1]+a[i][j];前缀和 } } while(q--) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("%lld ",mapp[x2][y2]-mapp[x1-1][y2]-mapp[x2][y1-1]+mapp[x1-1][y1-1]); } }