建两颗线段树分别存最大和最小值,模板题~
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=1e6+14; struct node { int l; int r; int sum; }segTree1[maxn*4],segTree2[maxn*4]; int a[maxn]; int N; int Q; int x,y; void build1 (int i,int l,int r) { segTree1[i].l=l; segTree1[i].r=r; if (l==r) { segTree1[i].sum=a[l]; return; } int mid=(l+r)>>1; build1(i<<1,l,mid); build1(i<<1|1,mid+1,r); segTree1[i].sum=max(segTree1[i<<1].sum,segTree1[i<<1|1].sum); } int query1 (int i,int l,int r) { if (l==segTree1[i].l&&r==segTree1[i].r) return segTree1[i].sum; int mid=(segTree1[i].l+segTree1[i].r)>>1; if (r<=mid) return query1(i<<1,l,r); else if (l>mid) return query1(i<<1|1,l,r); else return max(query1(i<<1,l,mid),query1(i<<1|1,mid+1,r)); } void build2 (int i,int l,int r) { segTree2[i].l=l; segTree2[i].r=r; if (l==r) { segTree2[i].sum=a[l]; return; } int mid=(l+r)>>1; build2(i<<1,l,mid); build2(i<<1|1,mid+1,r); segTree2[i].sum=min(segTree2[i<<1].sum,segTree2[i<<1|1].sum); } int query2 (int i,int l,int r) { if (l==segTree2[i].l&&r==segTree2[i].r) return segTree2[i].sum; int mid=(segTree2[i].l+segTree2[i].r)>>1; if (r<=mid) return query2(i<<1,l,r); else if (l>mid) return query2(i<<1|1,l,r); else return min(query2(i<<1,l,mid),query2(i<<1|1,mid+1,r)); } int main () { scanf ("%d %d",&N,&Q); for (int i=1;i<=N;i++) scanf ("%d",&a[i]); build1(1,1,N); build2(1,1,N); for (int i=0;i<Q;i++) { scanf ("%d %d",&x,&y); printf ("%d\n",query1(1,x,y)-query2(1,x,y)); } return 0; }