并不对劲的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 ...
随机推荐
- 安装wget 、 wget命令
今天给服务器安装新LNMP环境时,wget 时提示 -bash:wget command not found,很明显没有安装wget软件包.一般linux最小化安装时,wget不会默认被安装. 可以通 ...
- APP消息推送是否进入消息中心和click、receive事件分析
前端时间研究APP消息推送的机制,由于机型.版本的碎片化,消息推送的机制不太好理解,所以总结下,放在博文里以备后续查阅. 安卓Android系统的消息推送: 安卓 推送方式 应用状态 类型 消 ...
- mockjs从入门到精通视频教程
Mock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试.提供了以下模拟功能: (1)根据数据模板生成模拟数据 (2)模拟 Ajax 请求,生成并返回模拟数据 (3 ...
- PHP 二维数组去重方法
php二维数组的去重策略,如果需要根据某字段去重(其他字段可能不一致),那么需要使用循环策略,如果去重的都是相同的(字段,值),那么可以用序列化方式. $allComments = array_map ...
- 移动端——link标签
meta标签中提到了部分功能要结合link标签进行使用,link标签主要是存放CSS文件的地方,同时还有一些专属的移动端设置. <meta http-equiv="Content-Ty ...
- LC 640. Solve the Equation
Solve a given equation and return the value of x in the form of string "x=#value". The equ ...
- CSS三角形的实现原理及运用
原理 css盒模型 一个盒子包括: margin+border+padding+content– 上下左右边框交界处出呈现平滑的斜线. 利用这个特点, 通过设置不同的上下左右边框宽度或者颜色可以得到小 ...
- 14 statefulset (sts)控制器
statefulset (sts)控制器 可以用于部署有状态的服务,比如说redis,mysql ,zk等等... 1. 稳定且唯一的网络标志符:2. 稳定且持久的存储3. 有序,平滑地部署和扩展:4 ...
- 2018.05.17 nace关于采购订单的配置笔记
由于公司的打印都是使用nast作为记录表,在给日企中国客户做扩展时单独配置了一下nace的设置 ZM01作为采购订单批量打印的输出类型,ZM02作为采购订单创建变更时输出的pdf打印输出类型 1.TC ...
- Python把json格式的string对象转变成dict对象操作、Python3不能使用urllib2、urllib.parse.urlencode(params).encode(encoding='UTF8')
son格式的string对象转变成dict对象操作 content=eval(content)#json字典转化 Python3不能使用urllib2 直接使用urllib.request替换urll ...