题意:给一个$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. JUnit4.11 理论机制 @Theory 完整解读

    最近在研究JUnit4,大部分基础技术都是通过百度和JUnit的官方wiki学习的,目前最新的发布版本是4.11,结合代码实践,发现官方wiki的内容或多或少没有更新,Theory理论机制章节情况尤为 ...

  2. Codeforces Round #534 (Div. 2) D. Game with modulo(取余性质+二分)

    D. Game with modulo 题目链接:https://codeforces.com/contest/1104/problem/D 题意: 这题是一个交互题,首先一开始会有一个数a,你最终的 ...

  3. php 上传csv文件

    php fgetcsv()函数 定义和用法 fgetcsv() 函数从文件指针中读入一行并解析 CSV 字段. 与 fgets() 类似,不同的是 fgetcsv() 解析读入的行并找出 CSV 格式 ...

  4. 前端跨域之jsonp跨域

    jsonp跨域原理 原理:因为通过script标签引入的js是不受同源策略的限制的(比如baidu.com的页面加载了google.com的js).所以我们可以通过script标签引入一个js或者一个 ...

  5. css做中划线与文字排版

    html: <div class="spilt">    <span class="left"></span>    < ...

  6. 快速排序和归并排序(C语言)

    1.0快速排序算法 (1)分解 (2)递归求解 (3)合并 int partition(int a[],int p,int r) { int i=p,j=r+1; int x=a[p]; int te ...

  7. BroadCastRecieve

    首先介绍一下BroadCastRecieve有几种: 1.无序广播(普通广播):sendBroadcast()方式 2.有序广播:sendOrderedBroadcast()方式 3.粘性广播:sen ...

  8. LeetCode 6:Excel Sheet Column Number

    Given a column title as appear in an Excel sheet, return its corresponding column number. For exampl ...

  9. Map、Set、List初始化大小的影响

    import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Lis ...

  10. solr 启动过程分析

    http://www.cnblogs.com/likehua/p/4353608.html#top