[USACO2003 Mar]Cornfields玉米实验

题目链接:..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;
}


posted @ 2016-10-15 09:27  OxQ  阅读(129)  评论(0编辑  收藏  举报