题目链接:..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 ",mx-mn); } return 0; }