并不对劲的CF480E:Parking Lot
题目大意
有一个\(n\times m\)的网格,每个位置是黑色或者白色。\(k\)个操作,每个操作是将一个白格子染黑,操作后输出当前最大的白色正方形的边长。\(n,m,k\leq 2\times 10^3\)
题解
发现在每次操作是把白格子变黑,会使答案变小。维护“变小的最大值”听上去不太舒服。考虑把操作全都反过来,变成把黑格子染白。
这样每次操作之后,如果答案变大了,那么新的答案正方形一定包含在被操作的格子。
考虑对每个点记它左边最左的白格子和右边最右的白格子,操作时暴力更新与被操作点同行的点。
答案就是想找连续的一段与被操作的点在同一列,“段的长度”与“最左的右边界-最右的左边界”的最小值尽可能大。
发现可以判断答案是否大于一个数\(x\):当这一列上存在一个点,满足该点到从该点往上数第\(x\)个点满足“最左的右边界-最右的左边界”不少于\(x\),\(x\)就可以;反之就不可以。
可以用线段树或单调队列维护区间最左右边界和最右左边界。
这题知道判断解是否合法的方法后也不用二分,因为在处理过后答案就是不降的,而且不会超过\(min(n,m)\),而判断能否使答案增加1需要\(\Theta(n)\)或\(\Theta(n\space log\space n)\)的时间复杂度,所以可以每次暴力判断能否使答案增加。
总时间复杂度\(\Theta(n\times m+k\times m+k\times n)\)。
代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#define LL long long
#define rep(i,x,y) for(int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];~k;k=nxt[k])
#define maxn 2007
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
char ch[20];int f=0;
if(!x){putchar('0'),putchar('\n');return;}
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
}
int qx[maxn],qy[maxn],q[maxn],hd,tl;
int col[maxn][maxn],ans,lmx[maxn][maxn],rmx[maxn][maxn],n,m,k,res[maxn],tmp[maxn],dp[maxn][maxn];
char s[maxn];
int jud(int yy)
{
hd=1,tl=0;
rep(i,1,n)
{
while(hd<=tl&&q[hd]<i-(ans+1)+1)hd++;
while(hd<=tl&&lmx[q[tl]][yy]<=lmx[i][yy])tl--;
q[++tl]=i;
if(i<ans+1)continue;
tmp[i]=yy-lmx[q[hd]][yy]+1;
}
hd=1,tl=0;
rep(i,1,n)
{
while(hd<=tl&&q[hd]<i-(ans+1)+1)hd++;
while(hd<=tl&&rmx[q[tl]][yy]>=rmx[i][yy])tl--;
q[++tl]=i;
if(i<ans+1)continue;
tmp[i]+=rmx[q[hd]][yy]-yy;
}
rep(i,ans+1,n)if(tmp[i]>=ans+1)return 1;
return 0;
}
int main()
{
n=read(),m=read(),k=read();
rep(i,1,n)
{
scanf("%s",s+1);
rep(j,1,m)if(s[j]!='.')col[i][j]=1;
}
rep(i,1,k)qx[i]=read(),qy[i]=read(),col[qx[i]][qy[i]]=1;
rep(i,1,n)
{
rep(j,1,m)
{
if(col[i][j]){lmx[i][j]=j+1;continue;}
dp[i][j]=min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
ans=max(dp[i][j],ans);
if(j==1||col[i][j-1])lmx[i][j]=j;
else lmx[i][j]=lmx[i][j-1];
}
dwn(j,m,1)
{
if(col[i][j]){rmx[i][j]=j-1;continue;}
if(j==m||col[i][j+1])rmx[i][j]=j;
else rmx[i][j]=rmx[i][j+1];
}
}
dwn(i,k,1)
{
res[i]=ans;
col[qx[i]][qy[i]]=0;
int nl=qy[i],nr=qy[i];
while(nl-1>=1&&!col[qx[i]][nl-1])nl--;
while(nr+1<=m&&!col[qx[i]][nr+1])nr++;
rep(j,nl,nr)lmx[qx[i]][j]=nl,rmx[qx[i]][j]=nr;
while(jud(qy[i]))ans++;
}
rep(i,1,k)write(res[i]);
return (0-0);
}
并不对劲的CF480E:Parking Lot的更多相关文章
- [CF480E]Parking Lot
题意:给一个$n\times m$的网格,初始时有些地方不能选,给$k$个询问$(x,y)$,每次令$(x,y)$不能选,然后询问最大子正方形的边长 如果按原题来做,禁止选一个点对答案的影响是极其鬼畜 ...
- CF480E Parking Lot(单调队列+dp然鹅并不是优化)
(全英文题面所以直接放化简题意) 题意:在一个二维平面内,初始有一些点,然后每个时间点加入一些点,对每个时间点求平面内最大的无障碍正方形 (这次的题目是真的神仙啊...) 首先,考虑暴力,如果对每一个 ...
- CF480E Parking Lot(two-pointers + 单调队列优化)
题面 动态加障碍物,同时查询最大子正方形. n,m≤2000n,m\leq2000n,m≤2000 题解 加障碍不好做,直接离线后反着做,每次就是清除一个障碍物. 显然倒着做答案是递增的,而且答案的值 ...
- [LintCode] Parking Lot 停车场问题
Design a parking lot. see CC150 OO Design for details.1) n levels, each level has m rows of spots an ...
- [CareerCup] 8.4 Parking Lot 停车场问题
8.4 Design a parking lot using object-oriented principles. LintCode上的原题,请参见我的另一篇博客Parking Lot 停车场问题. ...
- Codeforces 46D Parking Lot
传送门 D. Parking Lot time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Round #135 (Div. 2) E. Parking Lot 线段数区间合并
E. Parking Lot time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
- Amazon Interview Question: Design an OO parking lot
Design an OO parking lot. What classes and functions will it have. It should say, full, empty and al ...
- HDOJ(HDU) 1673 Optimal Parking
Problem Description When shopping on Long Street, Michael usually parks his car at some random locat ...
随机推荐
- LVS之ipvsadm命令
目录: 安装 基本描述 用法 命令选项 示例 [安装] 可使用yum安装或者从官网下载安装包源码安装,两种方式皆可 先检查是否已经安装ipvsadm [root@v_machine1 ~]# yum ...
- IntelliJ IDEA 2017.3 搭建一个多模块的springboot项目(三)
你得先看完前两篇文章才可以进行第三章.这章我又新建了一个模块,起名叫project-core.建立方式与(一)里面一致,一个普通的maven模块.不需要勾选archetype的那种. 大家自己建好后, ...
- ionic3引用外部插件--百度地图及echart报表的使用
前言 ionic3提供的组件已经相当丰富咯,但是事实上有些特殊的需求,比如使用百度地图,或者第三方插件echart报表插件是,就不能用传统的方式去使用第三方插件咯,如何在Ionic3项目中使用第三方J ...
- Java获取当前时间及String、datetime、date相互转化
一.获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStrin ...
- HearthBuddy CSharpCodeProvider 如何编译cs文件
源码 源码1 namespace Hearthbuddy.Windows{ // Token: 0x02000041 RID: 65 public class MainWindow : W ...
- qt 之http学习
在Qt网络编程中,需要用到协议,即HTTP.它是超文本传输协议,它是一种文件传输协议. 新建工程名为“http”,然后选中QtNetwork模块,最后Base class选择QWidget.注意:如果 ...
- 前端知识点回顾之重点篇——jQuery实现的原理
jQuery jQuery的实现原理 参考:https://blog.csdn.net/zhouziyu2011/article/details/70256659 外层沙箱和命名空间$ 为了避免声明了 ...
- 1.ibatis核心类
- Ubuntu16.04格式化U盘
root@ubuntu:~# fdisk -l root@ubuntu:~# fdisk /dev/sdb 格式化U盘: root@ubuntu:~# fdisk -l sudo mkfs.ntfs ...
- mysql锁表机制分析
http://blog.csdn.net/u010942020/article/details/51925653