首页 > 其他分享 >ABC311E 题解

ABC311E 题解

时间:2023-08-01 23:37:16浏览次数:47  
标签:题解 个数 len 正方形 枚举 边长 ABC311E 左上角

看到官方题解是 \(O(n^2)\) 的 dp。

提供一个 \(O(n^2 \log_2 n)\) 的做法,考场思路,大概比较简单。


Description

给一个 \(H\) 行 \(W\) 列的网格,其中一些点被涂成黑色,求整个正方形内都未被涂黑的正方形的个数。


Solution

考场上首先想到的简单暴力做法,即枚举正方形左上角端点,然后枚举正方形边长,求目前枚举的正方形中有没有黑色格子。

这样做是 \(O(n^3)\) 的,接受不了。

所以我们需要减少或者优化掉一维的枚举。

考虑固定正方形的左上角,先 \(O(n^2)\) 枚举左上角 \((i,j)\),然后考虑如何快速计算答案。

显然对于满足条件的正方形,其内部黑色格子的数量是 \(0\),而在暴力枚举的过程中,正方形的边长不断增大,黑色格子的数量是单调不减的。

因此,如果以 \((i,j)\) 为左上角端点,边长为 \(len\) 的正方形中黑格个数 \(> 0\),那么左上端点不变,边长 \(\geq len\) 的正方形中黑格个数一定 \(> 0\),不可行。

而如果以 \((i,j)\) 为左上角端点,边长为 \(len\) 的正方形中黑格个数 \(= 0\),那么左上角不变,边长 \(\leq len\) 的正方形中黑格个数也一定 \(= 0\),可行。

换句话说,设 \(a_{len}\) 表示以 \((i,j)\) 为左上角的正方形中,边长为 \(len\) 的,其内部黑色格子的数量,那 \(a_{len}\) 随 \(len\) 单调不减,而我们要求出 \(a\) 数组前面连续的 \(0\) 的个数。

这满足单调性,可以二分边长 \(len\) ,对于每一个二分到的 \(len\) ,可以用二维前缀和 \(O(1)\) 算出正方形内黑色格子数。

不会二维前缀和的同学可以看一下 P2004

总复杂度 \(O(n^2 \log_2 n)\) ,此处的 \(n\) 即题目里的 \(H\),\(W\), \(3000\) 级别的,勉强可以过,最慢的点 \(528 ms\)。


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;
}

标签:题解,个数,len,正方形,枚举,边长,ABC311E,左上角
From: https://www.cnblogs.com/wonderfish/p/17599422.html

相关文章

  • CF1594A 题解
    题意\(t\)组数据(\(1\let\le1000\)),每组数据给一个整数\(n\)(\(1\len\le10^{18}\)),找出两个整数\(l\)和\(r\)($-10^{18}\lel<r\le10^{18}$)使$l+(l+1)+\ldots+(r-1)+r=n$。思路看到这个题目,首先会想到\(l=n\)且\(r=n\),但是发现题目要求\(......
  • CF1702E 题解
    题意\(t\)组数据($1\let\le10^{4}$),每组数据给一个偶数\(n\)(\(2\len\le2\cdot10^{5}\)),有\(n\)个多米诺骨牌,每块多米诺骨牌包含两个整数\(a_{i}\)和\(b_{i}\)(\(1\lea_{i},b_{i}\len\)),要求把这\(n\)块多米诺骨牌分入两个集合使得每个集合中的数互不相同,每个......
  • 题解 P9489【ZHY 的表示法】
    容易想到将所求差分,变为\([1,r]\)的答案减去\([1,l-1]\)的答案。直觉告诉我们所谓的“实数\(y\)”就是没事闲的,其实只需要整数就可以。然后这种酷似整除分块的结构提示我们很多\(y\)的取值都是多余的,只需要保留所有是\(x_i\)的倍数的取值就做到了不重不漏。要求\([1,k......
  • Codeforces Round 885 (Div. 2) 题解
    A.VikaandHerFriends看一下样例就可以发现,Vika以及她的朋友都不能走对角线,在这种情况下Vika和朋友的距离为偶数,且朋友一定追不上Vika所以直接判断Vika和朋友的距离是否都为偶数即可B.VikaandtheBridge显然贪心,枚举颜色,找到相邻距离最大的两块木板,记该距离为\(......
  • ARC089B 题解
    problem&blog。给一个比较暴躁的做法。若要求\((x,y)\)的颜色为White,等价于要求\((x+k,y)\)的颜色为Black;要求\((x,y)\)的颜色为Black,等价于要求\((x\bmod2k,y\bmod2k)\)为Black。于是将全部点以黑点的形式塞到左上角\(2k\times2k\)矩阵里。枚举黑白的「分......
  • Codeforces Round 887 (Div. 2) 题解
    A.Desorting题目的核心操作就是选定一个位置\(i\),使得:对于所有\(j\lei\),\(a_j\leftarrowa_j+1\)对于所有\(j>i\),\(a_j\leftarrowa_j-1\)这样一来,操作后\(a_{i+1}-a_i\)的值就会\(-2\)因为\(a_{i+1}-a_i<0\)时,也意味着\(a_i>a_{i+1}\),所以就达到了要求那么题......
  • RTSP流媒体服务器LntonNVR(源码版)平台硬件设备拔电关闭后不能自动重启的问题解决方案
    LntonNVR视频边缘计算网关可以放置在项目现场,7x24小时不间断使用,通电联网即可成功运行,部署操作十分简单。我们在测试时,将LntonNVR注册到服务启动,拔掉硬件设备的电源后,再次恢复供电,发现LntonNVR服务并没有再次启动。对此我们也进行了分析与排查。排查步骤如下:1、首先检查是否已经......
  • 【题解】Luogu[P2420] 让我们异或吧
    Link看到是树,又多组询问,立马想到类似的求和问题,异或不好理解,我们想求和怎么做,维护\(dis_i\)表示\(i\)节点到根的权值和,那么对于\(u,v\)两点路径上的权值和就是\(dis_u+dis_v-2\timesdis_{\mathrm{lca}(u,v)}\),这是很经典的问题了。事实上刚才的求和我们可以转化一下,我们......
  • 国标GB28181视频平台LntonGBS(源码版)国标平台出现报错“缺失dll文件”的问题解决方案
    LntonGBS是基于国标GB28181协议的视频云服务平台,它可以支持国标协议的设备接入,在视频能力上能实现直播、录像存储、检索与回放、云台控制、告警上报、语音对讲、平台级联等功能,既能作为业务平台使用,也能作为能力层平台调用。技术人员在用户服务器部署LntonGBS平台,提示缺失某个dll文......
  • P2216 理想的正方形 题解
    P2216理想的正方形(为什么要写这篇题解?因为我β搞的心态炸了)食用此题解所需:有基础的双端队列知识与一只可爱的\(C++\)传送门:起飞!1.思考嗯,一看数据范围,\(a,b\leq1,000\),就知道这道题一定是一道\(\operatorname{O}(ab)\)的题(因为输入就已经达到\(100,000\)级别了,就算......