题意:给一个$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. HDU1054 Strategic Game(最小点覆盖)

    Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  2. ubunut14.04 mentohust配置

      1.设置网卡eth0的IP地址和子网掩码 sudo ifconfig eth0 10.162.32.94 netmask 255.0.0.0 将IP地址改为:10.162.32.94,子网掩码改为 ...

  3. maven 压缩、合并 js, css

    转载自:http://blog.csdn.net/fangxing80/article/details/17639607 我们知道在 Web 应用开发中为了提高客户端响应速度,需要将页面使用的资源最小 ...

  4. windows远程桌面访问ubuntu12.04

    转载自 : http://blog.csdn.net/shuzui1985/article/details/7592569 1.dashboard----桌面共享 我们共享所使用的协议是rdp,所以我 ...

  5. HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTup

    Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.t ...

  6. WebView使用--文章集锦

    对于android WebView加载不出Html5网页的解决方法 在android4.4中webview的使用相对于之前版本的一些区别 理解WebKit和Chromium: Android 4.4 ...

  7. 在eclipse中使用JUnit4,以及使用JUnit4进行单元测试的技巧

    一 在eclipse中使用JUnit4 首先在工程上右键,选择属性,找到Java Builder Path,添加JUnit4的lib,如下图:   在要测试的类上右键新建 Junit test cas ...

  8. 一维和二维ST模板

    void init(){ ; i < n; i++) st[i][] = a[i]; ; ( << j) <= n; j++){ ; i + ( << j) - & ...

  9. Topcoder SRM 608 div1 题解

    Easy(300pts): 题目大意:有n个盒子,一共有S个苹果,每个盒子有多少个苹果不知道,但是知道每个盒子的苹果下限和上限.现在要至少选择X个苹果,问如果要保证无论如何都能获得至少X个苹果,至少需 ...

  10. django unresolved template

    参考:https://stackoverflow.com/questions/8487410/pycharm-django-1-3-static-url-in-templates-unresolved ...