[CF480E]Parking Lot
题意:给一个$n\times m$的网格,初始时有些地方不能选,给$k$个询问$(x,y)$,每次令$(x,y)$不能选,然后询问最大子正方形的边长
如果按原题来做,禁止选一个点对答案的影响是极其鬼畜的,不方便统计,所以我们离线倒序处理,先让所有询问的点不能选,然后反过来逐次让某些点可选,这样答案是不减的,而且更优的答案一定包含此次选的点
预处理出$up_{i,j}$表示$(i,j)$往上走最远可到的'.',$down_{i,j}$表示$(i,j)$往下走最远可到的'.'
于是对于某行,我们可以扫一遍求出所有跨越此行的正方形的最大边长
假设当前处理到此行的$[l,r]$,已经求得区间中$up$和$down$的最值
①若区间包含'X'或$\left|up-down\right|\lt r-l$,左端点++
②否则更新答案并右端点++
右端点移动时直接$O(1)$更新最值
左端点移动时用线段树$O(log_2n)$更新最值
整个过程是$O(nlog_2n)$的
所以每次加入一个可选点时,暴力更新这一列的$up,down$,统计这一行的答案并更新
需要访问单点值,所以用ZKW线段树又快又方便
#include<stdio.h> #define inf 2147483647 char s[2010][2010]; int x[2010],y[2010],up[2010][8010],ans[2010],down[2010][8010],M,m; int max(int a,int b){return a>b?a:b;} int min(int a,int b){return a<b?a:b;} void pu(int id,int x){ up[id][x]=max(up[id][x<<1],up[id][x<<1|1]); } void pd(int id,int x){ down[id][x]=min(down[id][x<<1],down[id][x<<1|1]); } int queryu(int id,int s,int t){ int c=-inf; for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){ if(~s&1)c=max(c,up[id][s^1]); if(t&1)c=max(c,up[id][t^1]); } return c; } void modifyu(int id,int p,int v){ p+=M; for(up[id][p]=v;p>>=1;)pu(id,p); } int queryd(int id,int s,int t){ int c=inf; for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){ if(~s&1)c=min(c,down[id][s^1]); if(t&1)c=min(c,down[id][t^1]); } return c; } void modifyd(int id,int p,int v){ p+=M; for(down[id][p]=v;p>>=1;)pd(id,p); } int getline(int x){ int l,r,maxy,miny,res; res=0; for(l=r=1;l<=m;l++){ if(l>r){ r++; l--; continue; } maxy=queryu(x,l,r); miny=queryd(x,l,r); while(maxy!=inf&&miny!=-inf&&miny-maxy>=r-l&&r<m){ res=max(res,r-l+1); r++; maxy=max(maxy,up[x][r+M]); miny=min(miny,down[x][r+M]); } if(r==m){ if(maxy!=inf&&miny!=-inf&&miny-maxy>=r-l)res=max(res,r-l+1); break; } } return res; } int main(){ int n,q,i,j; scanf("%d%d%d",&n,&m,&q); for(M=1;M<m+1;M<<=1); for(i=1;i<=n;i++)scanf("%s",s[i]+1); for(i=1;i<=q;i++){ scanf("%d%d",x+i,y+i); s[x[i]][y[i]]='X'; } for(i=1;i<=m;i++)s[0][i]=s[n+1][i]='X'; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(s[i][j]!='X'){ if(s[i-1][j]=='X') up[i][j+M]=i; else up[i][j+M]=up[i-1][j+M]; }else up[i][j+M]=inf; } } for(i=n;i>0;i--){ for(j=1;j<=m;j++){ if(s[i][j]!='X'){ if(s[i+1][j]=='X') down[i][j+M]=i; else down[i][j+M]=down[i+1][j+M]; }else down[i][j+M]=-inf; } } for(i=1;i<=n;i++){ for(j=M-1;j>0;j--){ pd(i,j); pu(i,j); } } ans[q]=0; for(i=1;i<=n;i++)ans[q]=max(ans[q],getline(i)); for(i=q;i>1;i--){ s[x[i]][y[i]]='.'; for(j=x[i];j<=n;j++){ if(s[j][y[i]]!='X'){ if(s[j-1][y[i]]=='X') modifyu(j,y[i],j); else modifyu(j,y[i],up[j-1][y[i]+M]); } } for(j=x[i];j>0;j--){ if(s[j][y[i]]!='X'){ if(s[j+1][y[i]]=='X') modifyd(j,y[i],j); else modifyd(j,y[i],down[j+1][y[i]+M]); } } ans[i-1]=max(ans[i],getline(x[i])); } for(i=1;i<=q;i++)printf("%d\n",ans[i]); }
[CF480E]Parking Lot的更多相关文章
- CF480E Parking Lot(单调队列+dp然鹅并不是优化)
(全英文题面所以直接放化简题意) 题意:在一个二维平面内,初始有一些点,然后每个时间点加入一些点,对每个时间点求平面内最大的无障碍正方形 (这次的题目是真的神仙啊...) 首先,考虑暴力,如果对每一个 ...
- CF480E Parking Lot(two-pointers + 单调队列优化)
题面 动态加障碍物,同时查询最大子正方形. n,m≤2000n,m\leq2000n,m≤2000 题解 加障碍不好做,直接离线后反着做,每次就是清除一个障碍物. 显然倒着做答案是递增的,而且答案的值 ...
- 并不对劲的CF480E:Parking Lot
题目大意 有一个\(n\times m\)的网格,每个位置是黑色或者白色.\(k\)个操作,每个操作是将一个白格子染黑,操作后输出当前最大的白色正方形的边长.\(n,m,k\leq 2\times 1 ...
- [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 ...
随机推荐
- Could not resolve com.android.support:multidex:1.0.2
http://blog.csdn.net/goodlixueyong/article/details/50992835
- egrep对于conf文件中去掉#注释,排除无用项
[root@localhost conf]# egrep -v "#|^$" nginx.conf.default > nginx.conf dd
- ansible 批量修改root密码
[root@sz_fy_virt_encrypt_33_239 fetch]# cat /opt/passwd.yml - hosts: web vars: path: /home/opsadmin ...
- DIV的变高与变宽
代码: <!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title&g ...
- 问题总结——window平台下grunt\bower安装后无法运行的问题
一.问题: 安装grunt或者bower后,在cmd控制台运行grunt -version 或者 bower -v会出现:“xxx不是内部或外部命令,也不是可运行的程序或批处理文件”,
- es6+最佳入门实践(5)
5.对象扩展 5.1.对象简写 在es5中,有这样一种写法 var name = "xiaoqiang"; var age = 12; var obj = { name : nam ...
- 在Idea中使用Eclipse编译器
Eclipse编译器对Javac编译器的优点如下: 1.Proceed on errors 如果使用Javac编译器,你除了在执行之前修复所有错误之外没有其它的选择.然而Eclipse编译器却可以不管 ...
- [bzoj3524==bzoj2223][Poi2014]Couriers/[Coci 2009]PATULJCI——主席树+权值线段树
题目大意 给定一个大小为n,每个数的大小均在[1,c]之间的数列,你需要回答m个询问,其中第i个询问形如\((l_i, r_i)\),你需要回答是否存在一个数使得它在区间\([l_i,r_i]\)中出 ...
- bzoj 3208 暴力
对于每个操作,直接暴力做就行了,询问的话搜一遍,然后 就这么水过去了. /************************************************************** ...
- Golang使用amqp发送消息
1.为什么使用信道(channel)而不使用TCP连接发送AMQP命令? 对操作系统来说频繁的建立和销毁TCP连接开销非常昂贵,而操作系统每秒建立的连接是有上限的,性能瓶颈不可避免,而只建立一条TCP ...