ABC311E 题解
看到官方题解是
提供一个
Description
给一个
Solution
考场上首先想到的简单暴力做法,即枚举正方形左上角端点,然后枚举正方形边长,求目前枚举的正方形中有没有黑色格子。
这样做是
所以我们需要减少或者优化掉一维的枚举。
考虑固定正方形的左上角,先
显然对于满足条件的正方形,其内部黑色格子的数量是
因此,如果以
而如果以
换句话说,设
这满足单调性,可以二分边长
不会二维前缀和的同学可以看一下 P2004。
总复杂度
Code
里面有一些注释。
#include<bits/stdc++.h>
using namespace std;
namespace IO{
template<typename T> inline void write(T x){
if(x<0) putchar('-'),x=-x;
if(x==0){
putchar('0'); return ;
}
if(x>9) write(x/10);
putchar(x%10+'0');
return ;
}
template<typename T> inline void read(T &x){
x=0; int w=1; char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1; ch=getchar();
}
while(isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x*=w; return ;
}
}
using namespace IO; //快读
#define writesp(x) write(x),putchar(' ')
#define writeln(x) write(x),putchar('\n')
#define inf 0x3f3f3f3f3f3f
#define mod 998244353
#define maxn 3010
#define int long long
#define pb emplace_back
int h,w,n,a[maxn][maxn],x,y,l,r,mid,ans=0;
int calc(int x1,int _y1,int x2,int y2){
return a[x2][y2]-a[x1-1][y2]-a[x2][_y1-1]+a[x1-1][_y1-1]; //二维前缀和
}
bool check(int i,int j,int mid){
return (calc(i,j,i+mid-1,j+mid-1)==0); //满足条件即为不含黑色方格
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
read(h); read(w); read(n);
memset(a,0,sizeof(a));
while(n--){
read(x); read(y); a[x][y]=1;
}
for(int i=1;i<=h;++i)
for(int j=2;j<=w;++j) a[i][j]+=a[i][j-1];
for(int i=1;i<=w;++i)
for(int j=2;j<=h;++j) a[j][i]+=a[j-1][i];
//计算二维前缀和数组
for(int i=1;i<=h;++i)
for(int j=1;j<=w;++j){
l=1; r=min(h-i+1,w-j+1); //二分,最小边长是 1,最大边长需要保证不越界
while(l<=r){
mid=(l+r)>>1;
if(check(i,j,mid)) l=mid+1;
else r=mid-1;
}
ans+=r; //二分出 r 为以 (i,j) 为端点的满足条件的正方形最大边长,也是正方形个数
}
writeln(ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?