建两颗线段树分别存最大和最小值,模板题~

#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;
}