题意:给一个$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. 浅析 nth-child(n) 和 nth-of-type(n)

    首先看一个例子 <div> <p>第一个段落</p> <p>第二个段落</p> </div> p:nth-child(2) { ...

  2. 转:使用 Nginx Upload Module 实现上传文件功能

    普通网站在实现文件上传功能的时候,一般是使用Python,Java等后端程序实现,比较麻烦.Nginx有一个Upload模块,可以非常简单的实现文件上传功能.此模块的原理是先把用户上传的文件保存到临时 ...

  3. 转:Spring AOP详解

    转:Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...

  4. 【uva11468-Substring】AC自动机+dp

    http://acm.hust.edu.cn/vjudge/problem/31655 题意:给定k个模板串,n个字符以及选择它的概率pro[i],要构造一个长度问L的字符串s,问s不包含任意一个模板 ...

  5. 分布式缓存Memcache

    Memcached是分布式的,也就是说它不是本地的.它基于网络连接(当然它也可以使用localhost)方式完成服务,本身它是一个独立于应用的程序或守护进程(Daemon方式). Memcached使 ...

  6. jquery hover事件中 fadeIn和fadeOut 效果不能及时停止

    $(".nav ul li").hover(function () { var id = $(this).attr("id"); $(".nav dl ...

  7. docker push 镜像到本地仓库

    root@ubuntu:# uname -a Linux ubuntu --generic #-Ubuntu SMP Mon Feb :: UTC x86_64 x86_64 x86_64 GNU/L ...

  8. mac air上archlinux的安装及优化

    前言 最近总感觉跑了两年多ubuntu系统的MacBookAir6,2越来越不行了,内存总是亮红灯,软件效率也低了不少.最直接的解决方法当然是换电脑,购买一台配置更好的,比如2017款xps,不过在我 ...

  9. HTML5-坦克大战一完成坦克上下左右移动的功能(一)

    坦克大战一完成坦克上下左右移动的功能 <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  10. ros bashrc 无法source setup.sh

    不知道什么时候开始的,莫名其妙首先是QT闪退,无法找到头文件,然后命令行进去catkin无法提示catkin_make 手动source之后就好了 问题出现在bashrc中source失败了 所以检查 ...