前言
一开始想如何染色成功。
发现只需要讨论四元环。
然后发现可以直接把规模缩成2*2矩阵。
题目大意
一个黑白网格图,你可以翻转任意行和任意列的颜色,求以此得到网格图最大黑色子矩阵面积。
做法
结论是一个矩阵如果任意一个2*2子矩阵都有偶数个黑色,一定可以通过翻转操作扭转为全黑。
易证必要充分。
然后就可以做经典问题。
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=2000+10;
bool bz[maxn][maxn],pd[maxn][maxn];
int up[maxn][maxn],sta[maxn];
int i,j,k,l,t,n,m,ans,top;
char get(){
char ch=getchar();
while (ch!='#'&&ch!='.') ch=getchar();
return ch;
}
int main(){
scanf("%d%d",&n,&m);
fo(i,1,n){
fo(j,1,m)
if (get()=='#') bz[i][j]=1;
}
fo(i,2,n)
fo(j,2,m){
t=(bz[i-1][j-1]+bz[i-1][j]+bz[i][j-1]+bz[i][j])%2;
if (!t) pd[i-1][j-1]=1;
}
fo(i,1,n-1)
fo(j,1,m-1) up[i][j]=pd[i][j]?up[i-1][j]+1:0;
ans=max(n,m);
fo(i,1,n-1){
top=0;
fo(j,1,m){
while (top&&up[i][j]<=up[i][sta[top]]){
ans=max(ans,(j-sta[top-1])*(up[i][sta[top]]+1));
top--;
}
sta[++top]=j;
}
}
printf("%d\n",ans);
}