CF480E Parking Lot

传送门  CF题粘的都是luogu题面因为有翻译qwq

恶意评分 实锤了

最优子矩阵问题++ 但是这把带修改不好做

最终复杂度要求是O(n^2) 考虑O(n)地处理一个修改带来的影响

自然想到l[i][j] r[i][j]存储左右拓展最远距离

然后发现向里面加点可能会改到很多行没法维护

所以我们正难则反就可以正常用l[][] r[][]

同时可以单调队列维护 开一个tmp[]存扩展最远距离然后逐步增大就行

判断增大一个一个加 反正答案<=n

这里用二维dp做了最开始的答案(后面都没有用dp)

Code:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<queue>
  6 #include<iostream>
  7 #define B puts("GGGGGGG");
  8 #define ms(a,b) memset(a,b,sizeof a)
  9 #define rep(i,a,n) for(int i = a;i <= n;i++)
 10 #define per(i,n,a) for(int i = n;i >= a;i--)
 11 #define inf 2147483647
 12 using namespace std;
 13 typedef long long ll;
 14 ll read() {
 15     ll as = 0,fu = 1;
 16     char c = getchar();
 17     while(c < '0' || c > '9') {
 18         if(c == '-') fu = -1;
 19         c = getchar();
 20     }
 21     while(c >= '0' && c <= '9') {
 22         as = as * 10 + c - '0';
 23         c = getchar();
 24     }
 25     return as * fu;
 26 }
 27 const int N = 2003;
 28 //head
 29 struct node {
 30     int x,y,res;
 31 }ans[N];
 32 int dp[N][N],l[N][N],r[N][N];
 33 bool a[N][N];
 34 int n,m,k;
 35 char s[N];
 36 int q[N],head,tail;
 37 int tmp[N];
 38 bool checkans(int x,int y) {
 39     head = 1,tail = 0;
 40     ms(tmp,0);
 41     rep(i,1,n) {
 42         while(head <= tail && l[q[tail]][y] >= l[i][y]) tail--;
 43         q[++tail] = i;
 44         while(q[head] <= i - x) head++;
 45         tmp[i] += l[q[head]][y];
 46     }
 47     head = 1,tail = 0;
 48     rep(i,1,n) {
 49         while(head <= tail && r[q[tail]][y] >= r[i][y]) tail--;
 50         q[++tail] = i;
 51         while(q[head] <= i - x) head++;
 52         tmp[i] += r[q[head]][y] - 1;
 53     }
 54     rep(i,x,n) if(tmp[i] >= x) return 1;
 55     return 0;
 56 }
 57 
 58 void output() {
 59     rep(i,1,n) {
 60         rep(j,1,m)
 61         printf("%d ",a[i][j]);
 62         puts("");
 63     }
 64     puts("-----------------");
 65 }
 66 
 67 int main() {
 68     n = read(),m = read(),k = read();
 69     rep(i,1,n) {
 70         scanf("%s",s+1);
 71         rep(j,1,m) a[i][j] = (s[j] == '.');
 72     }
 73     // output();
 74     rep(i,1,k) {
 75         ans[i].x = read(),ans[i].y = read();
 76         a[ans[i].x][ans[i].y] = 0;
 77     }
 78     // output();
 79     rep(i,1,n) per(j,m,1) {
 80         if(!a[i][j]) continue;
 81         if(i == 1 || j == m) {
 82             dp[i][j] = 1;
 83             ans[k].res = max(ans[k].res,1);
 84             continue;
 85         }
 86         dp[i][j] = min(dp[i-1][j],dp[i][j+1]);
 87         if(a[i-dp[i][j]][j+dp[i][j]]) dp[i][j]++;
 88         ans[k].res = max(ans[k].res,dp[i][j]);
 89     }
 90 
 91     rep(i,1,n) rep(j,1,m) l[i][j] = a[i][j] * (l[i][j-1] + 1);
 92     rep(i,1,n) per(j,m,1) r[i][j] = a[i][j] * (r[i][j+1] + 1);
 93     int tmpp = ans[k].res;
 94     per(i,k,2) {
 95         ans[i].res = tmpp;
 96         int x = ans[i].x,y = ans[i].y;
 97         a[x][y] = 1;
 98         // output();
 99         rep(j,1,m) l[x][j] = a[x][j] * (l[x][j-1] + 1);
100         per(j,m,1) r[x][j] = a[x][j] * (r[x][j+1] + 1);
101         while(checkans(tmpp+1,y)) tmpp++;
102     }
103     ans[1].res = tmpp;
104     rep(i,1,k) printf("%d
",ans[i].res);
105     return 0;
106 }
原文地址:https://www.cnblogs.com/yuyanjiaB/p/10045094.html