luogu1169 棋盘制作 (单调栈)
先预处理出来从每个位置 以0开始 往右交替最多能放多少格
然后就相当于对每一列做HISTOGRA
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=2020; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 int len[maxn][maxn][2]; 16 int N,M,ans1,ans2; 17 bool mp[maxn][maxn]; 18 int stk[maxn][2],sh; 19 20 inline void getans(int k,bool b){ 21 sh=0; 22 for(int i=1;i<=N;i++){ 23 int x=len[i][k][(i&1)^b],mt=i; 24 while(sh&&x<=stk[sh][0]){ 25 mt=min(mt,stk[sh][1]); 26 ans1=max(ans1,min(i-stk[sh][1],stk[sh][0])); 27 ans2=max(ans2,(i-stk[sh][1])*stk[sh][0]); 28 sh--; 29 } 30 stk[++sh][0]=x,stk[sh][1]=mt; 31 } 32 } 33 34 int main(){ 35 //freopen("","r",stdin); 36 int i,j,k; 37 N=rd(),M=rd(); 38 for(i=1;i<=N;i++) 39 for(j=1;j<=M;j++) 40 mp[i][j]=rd(); 41 for(i=1;i<=N;i++){ 42 for(j=M;j;j--){ 43 if(mp[i][j]) len[i][j][1]=len[i][j+1][0]+1; 44 else len[i][j][0]=len[i][j+1][1]+1; 45 } 46 } 47 for(i=1;i<=M;i++) 48 getans(i,0),getans(i,1); 49 printf("%d\n%d\n",ans1*ans1,ans2); 50 return 0; 51 }