代码改变世界

[HAOI2007]理想的正方形

2019-06-11 20:25  一只弱鸡丶  阅读(199)  评论(0编辑  收藏  举报

传送门:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long
#define re register
const int N=1005;
inline void read(int &a)
{
    a=0;
    int d=1;
    char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch^48;
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=(a<<3)+(a<<1)+(ch^48);
    a*=d;
}
int minq1[N][N],maxq1[N][N],minq2[N][N],maxq2[N][N],Q[N],q[N],a[N][N];
int main()
{
    int n,m,k;
    read(n);
    read(m);
    read(k);
    for(re int i=1;i<=n;i++)
        for(re int j=1;j<=m;j++)
            read(a[i][j]);
    int h1,h2,t1,t2;
    for(re int i=1;i<=n;i++)
    {
        h1=h2=t1=t2=1;
        for(re int j=1;j<=m;j++)
        {
            while(h1<t1&&j-Q[h1]>=k)
                h1++;
            while(h2<t2&&j-q[h2]>=k)
                h2++;
            while(h1<t1&&a[i][Q[t1-1]]<=a[i][j])
                t1--;
            while(h2<t2&&a[i][q[t2-1]]>=a[i][j])
                t2--;
            Q[t1++]=j,q[t2++]=j;
            if(j>=k)
            {
                maxq1[i][j-k+1]=a[i][Q[h1]];
                minq1[i][j-k+1]=a[i][q[h2]];
            }
        }
    }
    /*cout<<endl;
    for(re int i=1;i<=n;i++)
    {
        for(re int j=1;j<=m-k+1;j++)
            cout<<maxq1[i][j]<<" ";
        cout<<endl;
    }
    cout<<endl;
    for(re int i=1;i<=n;i++)
    {
        for(re int j=1;j<=m-k+1;j++)
            cout<<minq1[i][j]<<" ";
        cout<<endl;
    }*/
    for(re int i=1;i<=m-k+1;i++)
    {
        h1=h2=t1=t2=1;
        for(re int j=1;j<=n;j++)
        {
            while(h1<t1&&j-Q[h1]>=k)
                h1++;
            while(h2<t2&&j-q[h2]>=k)
                h2++;
            while(h1<t1&&maxq1[Q[t1-1]][i]<=maxq1[j][i])
                t1--;
            while(h2<t2&&minq1[q[t2-1]][i]>=minq1[j][i])
                t2--;
            Q[t1++]=j,q[t2++]=j;
            if(j>=k)
            {
                maxq2[j-k+1][i]=maxq1[Q[h1]][i];
                minq2[j-k+1][i]=minq1[q[h2]][i];
            }
        }
    }
    /*for(re int i=1;i<=n-k+1;i++)
    {
        for(re int j=1;j<=m-k+1;j++)
            cout<<maxq2[i][j]<<" ";
        cout<<endl;
    }
    for(re int i=1;i<=n-k+1;i++)
    {
        for(re int j=1;j<=m-k+1;j++)
            cout<<minq2[i][j]<<" ";
        cout<<endl;
    }*/
    int ans=0x3fffffff;
    for(re int i=1;i<=n-k+1;i++)
        for(re int j=1;j<=m-k+1;j++)
            ans=min(ans,maxq2[i][j]-minq2[i][j]);
    printf("%d",ans);
    return 0;
}