https://www.luogu.org/problemnew/show/P2280
二维前缀和差分的模板题。注意学习二维前缀和的求法,不用又down又right的。
#include<bits/stdc++.h> using namespace std; #define ll long long int sum[5005][5005]; int n,R; void solve(){ for(int j=1;j<=5000;j++) sum[0][j]+=sum[0][j-1]; for(int i=1;i<=5000;i++) sum[i][0]+=sum[i-1][0]; for(int i=1;i<=5000;i++){ for(int j=1;j<=5000;j++){ sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]; } } /*for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ printf(" %d",g[i][j]); } printf(" "); } printf(" "); for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ printf(" %d",sum[i][j]); } printf(" "); } printf(" ");*/ int ans=sum[R-1][R-1]; for(int j=R;j<=5000;j++) ans=max(ans,sum[R-1][j]-sum[R-1][j-R]); for(int i=R;i<=5000;i++) ans=max(ans,sum[i][R-1]-sum[i-R][R-1]); for(int i=R;i<=5000;i++){ for(int j=R;j<=5000;j++){ int tmp=sum[i][j]-sum[i-R][j]-sum[i][j-R]+sum[i-R][j-R]; ans=max(ans,tmp); } } printf("%d ",ans); } int main(){ while(~scanf("%d%d",&n,&R)){ R=min(R,5001); memset(sum,0,sizeof(sum)); while(n--){ int x,y,v; scanf("%d%d%d",&x,&y,&v); sum[x][y]+=v; } solve(); } }