CF 480 E. Parking Lot

http://codeforces.com/contest/480/problem/E

题意:

  给一个n*m的01矩阵,每次可以将一个0修改为1,求最大全0的矩阵。

分析:

  将询问离线,从后往前处理询问,相当于每次将一个1变成0,答案是递增的。

  用悬线法或者单调栈来求。

代码:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ; char a[N][N];
int x[N], y[N], L[N], R[N], U[N][N], D[N][N], q1[N], q2[N], ans[N], sk[N];
int Ans, n, m; void solve() {
for (int i=; i<=n; ++i)
for (int j=; j<=m; ++j)
U[i][j] = a[i][j] == '.' ? U[i-][j] + : ;
for (int i=n; i>=; --i)
for (int j=; j<=m; ++j)
D[i][j] = a[i][j] == '.' ? D[i+][j] + : ;
for (int i=; i<=n; ++i) { // 单调栈
U[i][] = U[i][m+] = -;
for (int top=,j=; j<=m+; ++j) {
while (top > && U[i][j] < U[i][sk[top]]) R[sk[top]] = j, top--;
sk[++top] = j;
}
for (int top=,j=m; j>=; --j) {
while (top > && U[i][j] < U[i][sk[top]]) L[sk[top]] = j, top --;
sk[++top] = j;
}
for (int j=; j<=m; ++j)
Ans = max(Ans, min(U[i][j], R[j] - L[j] - ));
}
/*memset(R, 0x3f, sizeof(R)); // 悬线法
for (int i=1; i<=n; ++i) {
int last = 0;
for (int j=1; j<=m; ++j) {
if (a[i][j] == '.') L[j] = max(L[j], last + 1);
else last = j, L[j] = 0;
}
last = m + 1;
for (int j=m; j>=1; --j) {
if (a[i][j] == '.') R[j] = min(R[j], last - 1);
else last = j, R[j] = m + 1;
}
for (int j=1; j<=m; ++j)
Ans = max(Ans, min(U[i][j], R[j] - L[j] + 1));
}*/
}
bool update(int x,int k) { // 判断能否组成k*k的方阵
int L1 = , R1 = , L2 = , R2 = ;
for (int j=; j<=m; ++j) {
while (L1 <= R1 && j - q1[L1] + > k) L1 ++;
while (L1 <= R1 && U[x][q1[R1]] >= U[x][j]) R1 --;
q1[++R1] = j; while (L2 <= R2 && j - q2[L2] + > k) L2 ++;
while (L2 <= R2 && D[x][q2[R2]] >= D[x][j]) R2 --;
q2[++R2] = j; if (j >= k && U[x][q1[L1]] + D[x][q2[L2]] - >= k) {
Ans = k;
return true;
}
}
return false;
}
void Change(int x,int y) {
a[x][y] = '.';
for (int i=x; i<=n; ++i) U[i][y] = a[i][y] == '.' ? U[i-][y] + : ;
for (int i=x; i>=; --i) D[i][y] = a[i][y] == '.' ? D[i+][y] + : ;
}
int main() {
n = read(), m = read(); int Q = read();
for (int i=; i<=n; ++i) scanf("%s",a[i]+);
for (int i=; i<=Q; ++i) {
x[i] = read(),y[i] = read();
a[x[i]][y[i]] = 'X';
}
solve();
for (int i=Q; i>=; --i) {
ans[i] = Ans;
Change(x[i], y[i]);
while (update(x[i], Ans + ));
}
for (int i=; i<=Q; ++i) printf("%d\n",ans[i]);
return ;
}

最新文章

  1. Bootstrap框架的学习(二)
  2. PHP mysql基础操作
  3. ECS挂载数据盘
  4. offline .net3.5
  5. Python面试题(二)
  6. runv start container 流程分析
  7. ios7技巧:你需要掌握的19个iOS7使用技巧
  8. [HDOJ3711]Binary Number(枚举)
  9. chrome 在home下生成 libpeerconnection.log
  10. 解析$.grep()源码及透过$.grep()看(两次取反)!!的作用
  11. ionic 安装教程
  12. 【实习记】2014-09-01从复杂到简单:一行命令区间查重+长整型在awk中的bug
  13. 章节八、3-如何用Chrome开发者工具查看元素
  14. FortiGate设置E-mail告警
  15. java读取配置文件的信息
  16. 【转】JQuery插件定义
  17. asp.net MVC之AuthorizeAttribute浅析
  18. LeetCode题解:Rotate List
  19. CentOS7安装 Apache HTTP 服务器
  20. iOS应用间相互跳转

热门文章

  1. linux 安装pip 和python3
  2. JSTL1.2学习总结
  3. Intellij IDEA 修改编辑器背景颜色
  4. ListView实现分页加载(一)制作Demo
  5. swift菜鸟入门视频教程-02-基本运算符
  6. 文本编辑器js插件
  7. BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡:贪心【最小匹配代价】
  8. Sublime Text 3中关闭记住上次打开的文件
  9. PHP Socket 简单使用
  10. Linux实用指令(2)