这种在矩形里面找矩形有固定的套路,不是容斥就是左右上下延伸,这个题就是向左向右延伸、、
然后手玩优化发现邻位转移比暴力要好一些,可以用splay统计,但复杂度不对
然后由于每一行互不影响于是可以单行同步操作
然后统计的时候就枚举列操作一遍
于是有限制最大值和最小值就转化为单调队列
所以这个题就是二维单调队列了
码:
#include<iostream>
#include<cstdio>
using namespace std;
#define N 1005
int a,b,n,i,j,v[N][N],z1[N],z2[N],z3[N],z4[N],q1[N][N],q3[N][N],qq1[N],qq3[N],zz1,zz2,zz3,zz4,ans=2000000009;
int main()
{
scanf("%d%d%d",&a,&b,&n);
for(i=1;i<=a;i++)
for(j=1;j<=b;j++)
scanf("%d",&v[i][j]);
for(i=1;i<=b;i++)z1[i]=z3[i]=1,z2[i]=z4[i]=0;
for(i=1;i<=a;i++)
{
for(j=1;j<=b;j++)
{
while(z1[j]<=z2[j]&&q1[j][z1[j]]<=i-n)++z1[j];
while(z1[j]<=z2[j]&&v[q1[j][z2[j]]][j]<v[i][j])--z2[j];
q1[j][++z2[j]]=i;
while(z3[j]<=z4[j]&&q3[j][z3[j]]<=i-n)++z3[j];
while(z3[j]<=z4[j]&&v[q3[j][z4[j]]][j]>v[i][j])--z4[j];
q3[j][++z4[j]]=i;
}
if(i>=n)
{
zz1=1;zz2=0;zz3=1;zz4=0;
for(j=1;j<=b;j++)
{
while(zz1<=zz2&&qq1[zz1]<=j-n)++zz1;
while(zz1<=zz2&&v[ q1[qq1[zz2]][z1[qq1[zz2]]] ][qq1[zz2]]<v[q1[j][z1[j] ]][j])--zz2;
qq1[++zz2]=j;
while(zz3<=zz4&&qq3[zz3]<=j-n)++zz3;
while(zz3<=zz4&&v[ q3[qq3[zz4]][z3[qq3[zz4]]] ][qq3[zz4]]>v[q3[j][z3[j] ]][j])--zz4;
qq3[++zz4]=j;
if(j>=n)
{ ans=min(ans,v[q1[qq1[zz1]][z1[qq1[zz1]]]][ qq1[zz1] ] -v[q3[qq3[zz3]][z3[qq3[zz3]]]][ qq3[zz3] ]);
}
}
}
}
printf("%d",ans);
}