注意:多组输入,maxx数组初始化为0,minx数组初始化为INF;query_max时,res初值为0,query_min时,res初值为INF。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN=200005;
const int INF=0x3f3f3f3f;
int a[MAXN],maxx[MAXN<<2],minx[MAXN<<2];
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
int nl,nr;
void pushup(int p){
maxx[p]=max(maxx[ls(p)],maxx[rs(p)]);
minx[p]=min(minx[ls(p)],minx[rs(p)]);
}
void build(int p,int l,int r){
if(l==r){maxx[p]=a[l];minx[p]=a[l];return;}
int mid=l+r>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
int query_max(int p, int l,int r){
int res=0;
if(nl<=l&&r<=nr) return maxx[p];
int mid=l+r>>1;
if(nl<=mid) res=max(res,query_max(ls(p),l,mid));
if(nr>mid) res=max(res,query_max(rs(p),mid+1,r));
return res;
}
int query_min(int p,int l,int r){
int res=INF;
if(nl<=l&&r<=nr)return minx[p];
int mid=l+r>>1;
if(nl<=mid) res=min(res,query_min(ls(p),l,mid));
if(nr>mid) res=min(res,query_min(rs(p),mid+1,r));
return res;
}
int main(){
int n,q;
scanf("%d%d",&n,&q);
memset(minx,INF,sizeof(minx));
memset(maxx,0,sizeof(maxx));
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
build(1,1,n);
while(q--){
scanf("%d%d",&nl,&nr);
printf("%d\n",query_max(1,1,n)-query_min(1,1,n));
}
return 0;
}
多么优美的线段树啊!