题目链接:..orz同找不到 要数据的叫我
题目大意:
题解:
单调队列预处理
mina[i][j]、maxa[i][j]存的是在第i行j-b+1~j中的最小值/最大值
这个就用单调队列预处理
对于每个询问,,我一行行扫下去
minn=min(mina[i][j+b-1]),r<=i<r+b (最大值同
因为预处理的是连续b个数中的最大/最小值 所以只用看j+b-1那列的
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 300
int a[maxn],l1,l2,r1,r2;
int q1[maxn],q2[maxn];
int mina[maxn][maxn],maxa[maxn][maxn];
int mymin(int x,int y){return (x<y)?x:y;}
int mymax(int x,int y){return (x>y)?x:y;}
int main()
{
//freopen("cornfld.in","r",stdin);
//freopen("cornfld.out","w",stdout);
int n,b,k,i,j,r,c;
scanf("%d%d%d",&n,&b,&k);
for (i=1;i<=n;i++)
{
l1=l2=1;r1=r2=0;
for (j=1;j<=n;j++)
{
scanf("%d",&a[j]);
while (l1<=r1 && a[q1[r1]]>=a[j]) r1--;
q1[++r1]=j;
while (l1<=r1 && q1[l1]<=j-b) l1++;
mina[i][j]=a[q1[l1]];
while (l2<=r2 && a[q2[r2]]<=a[j]) r2--;
q2[++r2]=j;
while (l2<=r2 && q2[l2]<=j-b) l2++;
maxa[i][j]=a[q2[l2]];
}
}
while (k--)
{
scanf("%d%d",&r,&c);
int mn=mina[r][c+b-1],mx=maxa[r][c+b-1];
for (i=r+1;i<r+b;i++)
{
mn=mymin(mn,mina[i][c+b-1]);
mx=mymax(mx,maxa[i][c+b-1]);
}printf("%d\n",mx-mn);
}
return 0;
}