前缀和
容斥原理及其应用
题目描述
题目链接:
https://ac.nowcoder.com/acm/contest/999/A
思考
首先二维前缀和代码
for(int i=1;i<=x;i++)
for(int j=1;j<=y;j++)
a[i][j]+=a[i][j-1];
for(int j=1;j<=y;j++)
for(int i=1;i<=x;i++)
a[i][j]+=a[i-1][j];
求长为r的正方形内所有数的和:
a[i][j]-a[i-r][j]-a[i][j-r]+a[i-r][j-r]
所有正方形和中最大的那一个:
ans=max(ans,a[i][j]-a[i-r][j]-a[i][j-r]+a[i-r][j-r]);
AC代码
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include<stdio.h>
#include<math.h>
#define Inf 1000000
using namespace std;
long long a[5050][5050];
int main(){
int n,r;
cin>>n>>r;
int x=0,y=0;
while(n--){
int xx,yy,v;
cin>>xx>>yy>>v;
a[xx+1][yy+1]=v;//让下标从1开始
x=max(xx+1,x);
y=max(yy+1,y);
}
//r比x、y大的情况特殊判断
x=max(x,r),y=max(y,r);
for(int i=1;i<=x;i++)
for(int j=1;j<=y;j++)
a[i][j]+=a[i][j-1];
for(int j=1;j<=y;j++)
for(int i=1;i<=x;i++)
a[i][j]+=a[i-1][j];
long long ans=0;
for(int i=r;i<=x;i++){
for(int j=r;j<=y;j++){
//cout<<i<<" "<<j<<a[i][j]<<endl;
ans=max(ans,a[i][j]-a[i-r][j]-a[i][j-r]+a[i-r][j-r]);
}
}
cout<<ans<<endl;
}