首先要知道,
于是枚举所有 矩阵,
- 若满足条件, 则将其中的数字赋为 , 否则赋为 .
- 可以将 覆盖
得到 的 矩阵,
记录每个数上方 最长 序列的长度 ,
对于每一行, 单调栈 从左向右寻找最大 矩阵,
如何使用单调栈寻找最大 矩阵 ?
求出每个数的 , .
设当前数编号为 , 则
#include<bits/stdc++.h>
#define reg register
int read(){
char c;
int s = 0, flag = 1;
while((c=getchar()) && !isdigit(c))
if(c == '-'){ flag = -1, c = getchar(); break ; }
while(isdigit(c)) s = s*10 + c-'0', c = getchar();
return s * flag;
}
const int maxn = 1006;
int N;
int M;
int Ans;
int A[maxn][maxn];
int B[maxn][maxn];
int Up[maxn][maxn];
int Rd[maxn];
int Ld[maxn];
bool chk(int i, int j){ return B[i][j]+B[i+1][j+1] <= B[i][j+1]+B[i+1][j]; }
int main(){
freopen("cool.in", "r", stdin);
freopen("cool.out", "w", stdout);
N = read(), M = read();
for(reg int i = 1; i <= N; i ++)
for(reg int j = 1; j <= M; j ++) A[i][j] = read(), B[i][j] = A[i][j];
for(reg int i = 1; i+1 <= N; i ++)
for(reg int j = 1; j+1 <= M; j ++) A[i][j] = !chk(i, j);
/*
for(reg int i = 1; i <= N; i ++){
for(reg int j = 1; j <= M; j ++)
printf("%d ", A[i][j]);
printf("
");
}
*/
N --, M --;
for(reg int j = 1; j <= M; j ++)
for(reg int i = 1; i <= N; i ++){
if(A[i][j] != 0) continue ;
Up[i][j] = Up[i-1][j] + 1;
}
/*
printf("===
");
for(reg int i = 1; i <= N; i ++){
for(reg int j = 1; j <= M; j ++) printf("%d ", Up[i][j]);
printf("
");
}
*/
for(reg int i = 1; i <= N; i ++){
std::stack <int> stk;
std::stack <int> stk_2;
memset(Rd, 0, sizeof Rd);
memset(Ld, 0, sizeof Ld);
for(reg int j = 1; j <= M; j ++){
while(!stk.empty() && stk.top() > Up[i][j]) Rd[stk_2.top()] = j, stk.pop(), stk_2.pop();
stk.push(Up[i][j]);
stk_2.push(j);
}
while(!stk.empty()) Rd[stk_2.top()] = M+1, stk.pop(), stk_2.pop();
for(reg int j = M; j >= 1; j --){
while(!stk.empty() && stk.top() > Up[i][j]) Ld[stk_2.top()] = j, stk.pop(), stk_2.pop();
stk.push(Up[i][j]);
stk_2.push(j);
}
while(!stk.empty()) Ld[stk_2.top()] = 0, stk.pop(), stk_2.pop();
/*
if(i == N){
printf("Fuck==========
");
for(reg int j = 1; j <= M; j ++) printf("%d ", Ld[j]);
printf("
");
for(reg int j = 1; j <= M; j ++) printf("%d ", Rd[j]);
printf("
");
}
*/
for(reg int j = 1; j <= M; j ++){
// if(j == 5 && i == 5) printf("%d %d %d %d
", Up[i][j], Rd[j], Ld[j], Rd[j]-Ld[j]-1);
Ans = std::max(Ans, (Up[i][j]+1) * (Rd[j]-Ld[j]));
}
}
printf("%d
", Ans);
return 0;
}