记录编号 192777 评测结果 AAAAAAAAAA
题目名称 [HAOI 2007]理想的正方形 最终得分 100
用户昵称 Gravatar炽烈的爱 是否通过 通过
代码语言 C++ 运行时间 1.608 s
提交时间 2015-10-12 21:01:44 内存使用 38.01 MiB
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#define N 1111
#define BUG system("pause")
using namespace std;
long long a,b,n;
long long map[N][N];
long long q[N][N],h[N],t[N],s,e,dq[N];
long long mx[N][N],ans,mn[N][N];
inline void read()
{
    scanf("%lld%d%d",&a,&b,&n);
    for(long long i=1;i<=a;i++)
        for(long long j=1;j<=b;j++)
            scanf("%lld",&map[i][j]);
}
inline void getmax()
{
    for(long long i=1;i<=b;i++)
		h[i]=1,t[i]=0;
    for(long long i=1;i<=a;i++)
    {
        for(long long j=1;j<=b;j++)
        {

            while(h[j]<=t[j]&&i-q[j][h[j]]+1>n) h[j]++;
            while(h[j]<=t[j]&&map[q[j][t[j]]][j]<=map[i][j]) t[j]--;
            q[j][++t[j]]=i;
        }
        e=0; s=1;
        for(long long j=1;j<=b;j++)
        {
            while(s<=e&&j-dq[s]+1>n) s++;
            while(s<=e&&map[q[dq[e]][h[dq[e]]]][dq[e]]<=map[q[j][h[j]]][j]) e--;
            dq[++e]=j;
            mx[i][j]=map[q[dq[s]][h[dq[s]]]][dq[s]];
        }
    }
}

inline void getmin()
{
    for(long long i=1;i<=b;i++) h[i]=1,t[i]=0;
    for(long long i=1;i<=a;i++)
    {
        for(long long j=1;j<=b;j++)
        {
            while(h[j]<=t[j]&&i-q[j][h[j]]+1>n) h[j]++;
            /*删除的时候,判断队首,如果队首元素下标小于当前段左边界就删除,
			不断删除队首直到队首元素下标大于等于当前段左边界
			(注意:这时队列肯定不为空),队首元素就是当前段的最优解。*/
            while(h[j]<=t[j]&&map[q[j][t[j]]][j]>=map[i][j]) t[j]--;
            /*为了保证单调性,每次插入的时候,先判断队尾元素,
			如果不比待插入元素小就删除,
			不断删除队尾直到队尾元素小于待插入元素或者队空。*/
            q[j][++t[j]]=i;
        }
        e=0; s=1;
        for(long long j=1;j<=b;j++)
        {
            while(s<=e&&j-dq[s]+1>n) s++;
            while(s<=e&&map[q[dq[e]][h[dq[e]]]][dq[e]]>=map[q[j][h[j]]][j]) e--;
            /*初始的时候分别把当前行前n-1个元素插入队尾。从第1列开始,
			每次取队首最优值,从队首删除无效元素,并将当前列+n-1号元素插入队尾。*/
            dq[++e]=j;
            mn[i][j]=map[q[dq[s]][h[dq[s]]]][dq[s]];
        }
    }
}

inline void go()
{
    getmin();
    getmax();
    ans=1LL<<60;
    for(long long i=n;i<=a;i++)
        for(long long j=n;j<=b;j++)
            ans=min(ans,mx[i][j]-mn[i][j]);
    printf("%lld\n",ans);
}

int main()
{
	freopen("square.in","r",stdin);
	freopen("square.out","w",stdout);
    read(),go();
    return 0;
}