线段树的基本题。询问给定区间内最大值与最小值的差。
分别建个最大堆和最小堆即可。
#include<stdio.h> #include<string.h> #include<iostream> #define MAXD 1000001 using namespace std; int N,Q,maxt[2*MAXD],mint[2*MAXD],a[MAXD],D; int great(int a,int b) { return a>b?a:b; } int small(int a,int b) { return a<b?a:b; } int Qmax(int x,int y) { int i=D+x-1,j=D+y+1,ans=0; for(;i^j^1;i>>=1,j>>=1) { if(~i&1) ans=great(ans,maxt[i^1]); if(j&1) ans=great(ans,maxt[j^1]); } return ans; } int Qmin(int x,int y) { int i=D+x-1,j=D+y+1,ans=0x3f3f3f3f; for(;i^j^1;i>>=1,j>>=1) { if(~i&1) ans=small(ans,mint[i^1]); if(j&1) ans=small(ans,mint[j^1]); } return ans; } int main() { //freopen("test.txt","r",stdin); scanf("%d%d",&N,&Q); for(D=1;D<N;D<<=1); int i; for(i=1;i<=N;i++) scanf("%d",&a[i]); memset(maxt,0,sizeof(maxt)); for(i=1;i<=N;i++) maxt[D+i]=a[i]; for(i=D-1;i>0;i--) maxt[i]=great(maxt[i<<1],maxt[i<<1|1]); memset(mint,0x3f,sizeof(mint)); for(i=1;i<=N;i++) mint[D+i]=a[i]; for(i=D-1;i>0;i--) mint[i]=small(mint[i<<1],mint[i<<1|1]); int x,y; for(i=1;i<=Q;i++) { scanf("%d%d",&x,&y); printf("%d\n",Qmax(x,y)-Qmin(x,y)); } return 0; }