CF407D Largest Submatrix 3

cf

luogu

By their own vegetables to the self-closing / kk

Since it is a sub-matrix, then the usual routine enumeration matrix upper and lower boundaries, then \ (O (n) \) scanning to solve this problem was to enumerate the right point from left to right, then look up to the left point into which, it is calculated for each number in the upper and lower boundaries, the number of positions in the far right to his left, and then left endpoint must be greater than this position (if it can not contain the same columns in this column), then the left border is legitimate within the selected section to the left of the extended maximum position. every time extension at the border, and then let a few more out of this line updates of each column to the left of the most extended position, here use to set, so to \ (O (n ^ 3logn ) \)

Consider optimization, from the bottom to the upper boundary of the enumeration, and then remember what the next column for each boundary \ (j \) is left up to the extended position, the lower boundary of the enumeration from top to bottom, then spend a row information and updates this information on a boundary line, then you would fall \ (log \) , implementation of this process is about to open a barrel record appears to the right-most position of an element

#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db double

using namespace std;
const int N=400+10;
const db eps=1e-5;
int rd()
{
    int x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int n,m,a[N][N],p[N][N],ans,bk[N*N];

int main()
{
    //////qwq
    n=rd(),m=rd();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            a[i][j]=rd();
    for(int i=n;i;--i)
    {
        for(int k=1;k<=m;++k)
        {
            p[i][k]=max(p[i][k-1],bk[a[i][k]]+1);
            bk[a[i][k]]=k;
            ans=max(ans,k-p[i][k]+1);
        }
        for(int k=1;k<=m;++k) bk[a[i][k]]=0;
        for(int j=i+1;j<=n;++j)
        {
            for(int k=1,hd=1;k<=m;++k)
            {
                p[j][k]=a[i][k]==a[j][k]?k+1:max(p[j][k],max(bk[a[i][k]],bk[a[j][k]])+1);
                p[j][k]=max(p[j][k],p[j-1][k]);
                bk[a[i][k]]=bk[a[j][k]]=k;
                hd=max(hd,p[j][k]);
                ans=max(ans,(j-i+1)*(k-hd+1));
            }
            for(int k=1;k<=m;++k) bk[a[i][k]]=bk[a[j][k]]=0;
        }
    }
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/smyjr/p/11601339.html