题意:给你一个5000*5000的格子,有些格子里面有值,询问一个的正方形的最大值
由于数据范围是5000,刚好不需要离散化,直接预处理出二维前缀和,利用差分O(1)查询每个正方形,复杂度
二维前缀和写法有很多,主要是两种
for(i=1;i<=5001;i++)
for(j=1;j<=5001;j++) a[i][j]+=a[i-1][j];
for(i=1;i<=5001;i++)
for(j=1;j<=5001;j++) a[i][j]+=a[i][j-1];
和
for(int i=1;i<=5001;i++){
for(int j=1;j<=5001;j++){
a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
}
}
然后每次询问的时候利用容斥原理做一下
比如一个以为右上角,为左下角的矩阵的值为
可以自己画图手推一下
代码
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();
int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
}
const int N=5005;
int t[N][N],m,n,r;
int main(){
n=read(),r=read();
for(int i=1;i<=n;i++){
int x=read(),y=read(),a=read();
t[x+1][y+1]+=a;
}
for(int i=1;i<=5001;i++){
for(int j=1;j<=5001;j++){
a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
}
}
int ans=0;
for(int i=r;i<=5001;i++){
for(int j=r;j<=5001;j++){
ans=max(ans,t[i][j]-t[i][j-r]-t[i-r][j]+t[i-r][j-r]);
}
}
cout<<ans;
}