MINSUB - Largest Submatrix

MINSUB - Largest Submatrix

no tags 

 

You are given an matrix M (consisting of nonnegative integers) and an integer K.  For any submatrix of M' of M define min(M') to be the minimum value of all the entries of M'.  Now your task is simple:  find the maximum value of min(M') where M' is a submatrix of M of area at least K (where the area of a submatrix is equal to the number of rows times the number of columns it has).

Input

The first line contains a single integer T (T ≤ 10) denoting the number of test cases, T test cases follow.  Each test case starts with a line containing three integers, R (R ≤ 1000), C (C ≤ 1000) and K (K ≤ R * C) which represent the number of rows, columns of the matrix and the parameter K.  Then follow R lines each containing C nonnegative integers, representing the elements of the matrix M.  Each element of M is ≤ 10^9

Output

For each test case output two integers:  the maximum value of min(M'), where M' is a submatrix of M of area at least K, and the maximum area of a submatrix which attains the maximum value of min(M').  Output a single space between the two integers.

Example

Input:
2
2 2 2
1 1
1 1
3 3 2
1 2 3
4 5 6
7 8 9

Output:
1 4
8 2
分析:首先二分答案M,其次改写成01矩阵,这样变成求最大的全1子矩阵;
   最大全1子矩阵那么可以单调栈解决;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
const int maxn=1e3+10;
const int N=1e3+10;
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
int n,m,k,t,qu[maxn],a[maxn][maxn],v[maxn][maxn],le[maxn],ret,ma,now;
bool ok(int x)
{
    now=0;
    int i,j;
    rep(i,1,n)rep(j,1,m)v[i][j]=(a[i][j]>=x?v[i-1][j]+1:0);
    rep(i,1,n)
    {
        rep(j,1,m+1)
        {
            if(!qu[0])qu[++qu[0]]=v[i][j],le[qu[0]]=j;
            else if(v[i][j]>qu[qu[0]])qu[++qu[0]]=v[i][j],le[qu[0]]=j;
            else if(v[i][j]<qu[qu[0]])
            {
                int tmp;
                while(qu[0]>=1&&v[i][j]<=qu[qu[0]])
                {
                    now=max(now,(j-le[qu[0]])*qu[qu[0]]);
                    tmp=le[qu[0]];
                    qu[0]--;
                }
                qu[++qu[0]]=v[i][j];
                le[qu[0]]=tmp;
            }
        }
        qu[0]--;
    }
    return now>=k;
}
int main()
{
    int i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        rep(i,1,n)rep(j,1,m)scanf("%d",&a[i][j]);
        int l=1,r=1e9;
        while(l<=r)
        {
            int mid=l+r>>1;
            if(ok(mid))ret=mid,ma=now,l=mid+1;
            else r=mid-1;
        }
        printf("%d %d\n",ret,ma);
    }
    return 0;
}
posted @ 2017-02-27 09:05  mxzf0213  阅读(260)  评论(0编辑  收藏  举报