思路:水题,线段树的基本操作即可。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 50010 using namespace std; int n,q; struct nond{ int l,r,min,max; }tree[MAXN*4]; void up(int now){ tree[now].max=max(tree[now*2].max,tree[now*2+1].max); tree[now].min=min(tree[now*2].min,tree[now*2+1].min); return ; } void build(int now,int l,int r){ tree[now].l=l;tree[now].r=r; if(tree[now].l==tree[now].r){ scanf("%d",&tree[now].max); tree[now].min=tree[now].max; return ; } int mid=(tree[now].l+tree[now].r)/2; build(now*2,l,mid); build(now*2+1,mid+1,r); up(now); } int querymax(int now,int l,int r){ if(tree[now].l==l&&tree[now].r==r) return tree[now].max; int mid=(tree[now].l+tree[now].r)/2; if(r<=mid) return querymax(now*2,l,r); else if(l>mid) return querymax(now*2+1,l,r); else return max(querymax(now*2,l,mid),querymax(now*2+1,mid+1,r)); } int querymin(int now,int l,int r){ if(tree[now].l==l&&tree[now].r==r) return tree[now].min; int mid=(tree[now].l+tree[now].r)/2; if(r<=mid) return querymin(now*2,l,r); else if(l>mid) return querymin(now*2+1,l,r); else return min(querymin(now*2,l,mid),querymin(now*2+1,mid+1,r)); } int main(){ scanf("%d%d",&n,&q); build(1,1,n); for(int i=1;i<=q;i++){ int x,y; scanf("%d%d",&x,&y); printf("%d\n",querymax(1,x,y)-querymin(1,x,y)); } }