HDU 6957 Maximal submatrix(懸線法+單調棧)
阿新 • • 發佈:2022-05-17
分析:類似最大子矩陣問題 判斷條件修改一下就好
up[i][j] 表示點(i,j)最大向上擴充套件的高度 這個可以預處理出來
剩下的就是單調棧的模板題型 求最大矩形面積
對每一行進行單調棧處理 L[i][j] R[i][j]
分別表示點(i,j) 最大向左向右擴充套件的位置
#include<bits/stdc++.h> using namespace std; #define lowbit(x) x&(-x) #define ll long long const int maxn=2e3+5; int n,m,ans; int a[maxn][maxn],L[maxn][maxn],R[maxn][maxn],up[maxn][maxn]; void solve(); stack<int>Q; int main(){ int T; cin>>T; while(T--)solve(); return 0; } void solve(){ ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]>=a[i-1][j]) up[i][j]=up[i-1][j]+1; else up[i][j]=1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ while(!Q.empty()&&up[i][Q.top()]>up[i][j])R[i][Q.top()]=j-1,Q.pop(); Q.push(j); } while(!Q.empty())R[i][Q.top()]=m,Q.pop(); for(int j=m;j>=1;j--){ while(!Q.empty()&&up[i][Q.top()]>up[i][j])L[i][Q.top()]=j+1,Q.pop(); Q.push(j); } while(!Q.empty())L[i][Q.top()]=1,Q.pop(); for(int j=1;j<=m;j++) ans=max(ans,up[i][j]*(R[i][j]-L[i][j]+1)); } cout<<ans<<endl; }