交叉非常好维护 可以转化成最大矩形面积 ——单调栈!
至于最大正方形面积 每次求矩形面积的时候找比较小的边平方就OK
Code:
1 // luogu-judger-enable-o2 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #include<vector> 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 = 2005; 28 //head 29 int n,m; 30 bool a[N][N]; 31 int h[N]; 32 int stk[N],top; 33 int maxq,maxj; 34 int main() { 35 n = read(); 36 m = read(); 37 rep(i,1,n) rep(j,1,m) a[i][j] = read(); 38 rep(i,1,n) { 39 rep(j,1,m) { 40 if(i > 1 && a[i][j] ^ a[i-1][j]) h[j]++; 41 else h[j] = 1; 42 } 43 int cur = 1; 44 while(cur <= m) { 45 top = 0; 46 stk[top] = cur - 1; 47 stk[++top] = cur++; 48 while(cur <= m && (a[i][cur] ^ a[i][cur-1])) { 49 while(top && h[stk[top]] > h[cur]) { 50 int tmp = min(h[stk[top]],cur - stk[top-1] - 1); 51 maxq = max(maxq,tmp * tmp); 52 maxj = max(maxj,h[stk[top]] * (cur-stk[top-1] - 1)); 53 top--; 54 } 55 stk[++top] = cur++; 56 } 57 while(top) { 58 int tmp = min(h[stk[top]],cur - stk[top-1] - 1); 59 maxq = max(maxq,tmp * tmp); 60 maxj = max(maxj,h[stk[top]] * (cur - stk[top-1] - 1)); 61 top--; 62 }//不合法就弹光 63 } 64 } 65 printf("%d\n%d\n",maxq,maxj); 66 return 0; 67 }