https://ac.nowcoder.com/acm/contest/882/H
求第二大全1矩形面积,单调栈
(之前写的单调栈已经看不懂了,ε=ε=ε=(#>д<)ノ)
注意同一个矩形不要算重了
例
1 5
11111
答案应该是4,而不是5
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<list>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int N=1e3+5;
char mp[N][N];
int h[N];
int l[N],r[N];
int n,m;
int s[N],cnt=0;
int ans[15]={0,0,0};
bool vis[N][N];
void insert(int x){
if(x>=ans[1]){
ans[2]=ans[1];
ans[1]=x;
}
else if(x>=ans[2]){
ans[2]=x;
}
}
void solve(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mp[i][j]=='0') h[j]=0;
else h[j]++;
}
//单调栈求左边界
cnt=0;
for(int j=1;j<=m;j++){
while(cnt&&h[s[cnt]]>=h[j]) cnt--;
if(cnt) l[j]=s[cnt]+1;
else l[j]=1;
s[++cnt]=j;
}
//单调栈求右边界
cnt=0;
for(int j=m;j>=1;j--){
while(cnt&&h[s[cnt]]>=h[j]) cnt--;
if(cnt) r[j]=s[cnt]-1;
else r[j]=m;
s[++cnt]=j;
}
for(int j=1;j<=m;j++){
int H=h[j];
int W=r[j]-l[j]+1;
if(vis[l[j]][r[j]]) continue;
vis[l[j]][r[j]]=true;
if(H*W){
insert(H*W);
insert((H-1)*W);
insert(H*(W-1));
}
}
for(int j=1;j<=m;j++){
vis[l[j]][r[j]]=false;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
}
solve();
printf("%d\n",ans[2]);
return 0;
}