bzoj1047: [HAOI2007]理想的正方形

我发现我是越来越傻叉了。。

本机运行死活过不去数据,拍了贼久就是不出错,一怒之下直接交居然A了。。。

我的做法是先把当前行j-k+1~j列的最值用单调队列搞出来

然后再搞一次行的单调队列的最值

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;

LL a[1100][1100];
LL mx[1100][1100],mn[1100][1100];//lmx[i][j]表示第i行第j-k+1~j列 的最大值 
struct node
{
    int p;LL d;
}mxq[1100],mnq[1100];int mxl,mxr,mnl,mnr;
int main()
{
    freopen("data.in","r",stdin);
    freopen("1.out","w",stdout);
    
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lld",&a[i][j]);
            
    for(int i=1;i<=n;i++)
    {
        mxl=1,mxr=0,mnl=1,mnr=0;
        for(int j=1;j<=m;j++)
        {
            while(mxl<=mxr&&mxq[mxl].p+k-1<j)mxl++;
            while(mxl<=mxr&&mxq[mxr].d<=a[i][j])mxr--;
            mxr++;
            mxq[mxr].p=j, mxq[mxr].d=a[i][j];
            mx[i][j]=mxq[mxl].d;
            
            while(mnl<=mnr&&mnq[mnl].p+k-1<j)mnl++;
            while(mnl<=mnr&&mnq[mnr].d>=a[i][j])mnr--;
            mnr++;
            mnq[mnr].p=j, mnq[mnr].d=a[i][j];
            mn[i][j]=mnq[mnl].d;
        }
    }
    
    LL ans=(1LL<<61);
    for(int j=k;j<=m;j++)
    {
        mxl=1,mxr=0,mnl=1,mnr=0;
        for(int i=1;i<=n;i++)
        {
            while(mxl<=mxr&&mxq[mxl].p+k-1<i)mxl++;
            while(mxl<=mxr&&mxq[mxr].d<=mx[i][j])mxr--;
            mxr++;
            mxq[mxr].p=i, mxq[mxr].d=mx[i][j];
            
            while(mnl<=mnr&&mnq[mnl].p+k-1<i)mnl++;
            while(mnl<=mnr&&mnq[mnr].d>=mn[i][j])mnr--;
            mnr++;
            mnq[mnr].p=i, mnq[mnr].d=mn[i][j];
            
            if(i-k+1>0)ans=min(ans,mxq[mxl].d-mnq[mnl].d);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2018-04-21 16:24  AKCqhzdy  阅读(167)  评论(0编辑  收藏  举报