H . Maximal submatrix(单调栈)

Given a matrix of n rows and m columns,find the largest area submatrix which is non decreasing on each column

Input

The first line contains an integer T(1T10)representing the number of test cases.

For each test case, the first line contains two integers n,mn,m(1n,m210^3)representing the size of the matrix 

the next nn line followed. the ii-th line contains mm integers vijvij(1vij510^3) representing the value of matrix

It is guaranteed that there are no more than 2 testcases with nm>10000

Output

For each test case, print a integer representing the Maximal submatrix

Samples

Input Copy
1
2 3
1 2 4
2 3 3
Output
4



题目大意:给出一个N * M矩阵,求出最大的列上升子矩阵
for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(a[i][j]>=a[i-1][j]){
                    s[i][j]=s[i-1][j]+1;
                }
                else{
                    s[i][j]=1;
                }
            }
        }

然后对于这个题处理出来这个矩阵之后,就转化为这个题了:传送门

就是对于每一行对该矩阵求最大的子矩阵大小


#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=5e3+100;
int a[maxn][maxn];
int s[maxn][maxn];
int h[maxn];
int q[maxn];
int l[maxn],r[maxn];
int n,m;
int judge(int h[]){
    h[0] = h[m + 1] = -1;
    int tt = -1;
    q[++ tt] = 0;
    for(int i = 1; i <= m; i ++)
    {
        while(h[q[tt]] >= h[i])  tt --;
        l[i] = q[tt]+1;
        q[++ tt] = i;
    }
    tt = -1;
    q[++ tt] = m + 1;
    for(int i = m; i; i --)
    {
        while(h[q[tt]] >= h[i])  tt --;
        r[i] = q[tt]-1;
        q[++ tt] = i;
    }
    int res = 0;
    for(int i = 1; i <= m; i ++)  res = max(res,h[i]*(r[i]-l[i]+1));
    return res;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>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]){
                    s[i][j]=s[i-1][j]+1;
                }
                else{
                    s[i][j]=1;
                }
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            ans=max(ans,judge(s[i]));
        }
        cout<<ans<<endl;
    }
}

 




posted @ 2021-07-23 10:44  lipu123  阅读(112)  评论(0)    收藏  举报