题意:给一个$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的更多相关文章

  1. CF480E Parking Lot(单调队列+dp然鹅并不是优化)

    (全英文题面所以直接放化简题意) 题意:在一个二维平面内,初始有一些点,然后每个时间点加入一些点,对每个时间点求平面内最大的无障碍正方形 (这次的题目是真的神仙啊...) 首先,考虑暴力,如果对每一个 ...

  2. CF480E Parking Lot(two-pointers + 单调队列优化)

    题面 动态加障碍物,同时查询最大子正方形. n,m≤2000n,m\leq2000n,m≤2000 题解 加障碍不好做,直接离线后反着做,每次就是清除一个障碍物. 显然倒着做答案是递增的,而且答案的值 ...

  3. 并不对劲的CF480E:Parking Lot

    题目大意 有一个\(n\times m\)的网格,每个位置是黑色或者白色.\(k\)个操作,每个操作是将一个白格子染黑,操作后输出当前最大的白色正方形的边长.\(n,m,k\leq 2\times 1 ...

  4. [LintCode] Parking Lot 停车场问题

    Design a parking lot. see CC150 OO Design for details.1) n levels, each level has m rows of spots an ...

  5. [CareerCup] 8.4 Parking Lot 停车场问题

    8.4 Design a parking lot using object-oriented principles. LintCode上的原题,请参见我的另一篇博客Parking Lot 停车场问题. ...

  6. Codeforces 46D Parking Lot

    传送门 D. Parking Lot time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. 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 ...

  8. 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 ...

  9. HDOJ(HDU) 1673 Optimal Parking

    Problem Description When shopping on Long Street, Michael usually parks his car at some random locat ...

随机推荐

  1. angular js module 的理解

    module其实就是一个容器,里面可以装controller,service,directive,filter等, 官网的解释是:Module :A container for the differe ...

  2. AWS文档与用户指南

    AWS Command Line Interface http://docs.amazonaws.cn/cli/latest/userguide/cli-chap-welcome.html VM Im ...

  3. All in One到”分布式“迁移过程中的坑

    为什么“分布式”要加引号? 与其他公司提高并发性能的场景可能不太一样,我们的系统之前是多个模块共用一个tomcat来运行的(All in One),模块有很多,光安装包就几十个.当某个模块或某几个模块 ...

  4. HASHMAP原理解析,不错的文章

    http://blog.csdn.net/vking_wang/article/details/14166593

  5. 【Foreign】无聊的计算姬 [Lucas][BSGS]

    无聊的计算姬 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 6 2 2 3 4 3 2 ...

  6. Ubuntu 下nginx 的卸载 与重新装

    由于本人把自己服务器的nginx 给玩坏了,不得已选择卸载重新安装,(先让我哭一会) 然后我把/usr/sbin/nginx  和/etc/nginx 和/usr/share/nginx 和 /usr ...

  7. linux system函数分析

    system函数是在应用编程里面想调用外部命令时最方便的方式了,除非想要获取命令行执行的输出信息, 那system就不行了,需要用popen.但是system内部具体怎么实现及怎么处理它的返回值经常被 ...

  8. easyUi根据一个日期给另一日期自动赋值的js

    $('#loanbegindate').datebox({ onSelect:function(date){ changeDate(); } }); $('#loanterm,#loantermtyp ...

  9. Ubunt 服务教程集锦

    1.Ubuntu管理服务安装(强烈推荐最好用Xshell和Xftp): 序号 服务名 介绍 教程地址 windows客户端 1 VNC 可以图形界面管理Ubuntu ubuntu安装vncserver ...

  10. [ nginx ] 代理后端tomcat 无法显示图片报错:ERR_CONTENT_LENGTH_MISMATCH

    问题日志如下: