来源:POJ3264
线段树的题目
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,q;
const int MAXN = 200000+10;
const int N = 50000+10;
const int INF = 0x3f3f3f3f;
int mmax,mmin;
int a[MAXN];
struct Tree{
int l,r;
int mmax,mmin;//维护的值多了,就直接使用结构体
Tree():mmax(0),mmin(0){}
};
Tree tree[MAXN*4];
void build(int rt,int l,int r){
tree[rt].l=l;
tree[rt].r=r;
if(l==r){
tree[rt].mmax=tree[rt].mmin=a[l];//当前是叶子节点的时候,我们想要维护的最大值和最小值其实是一个值
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
tree[rt].mmax=max(tree[rt<<1].mmax,tree[rt<<1|1].mmax);
tree[rt].mmin=min(tree[rt<<1].mmin,tree[rt<<1|1].mmin);
}
void query(int rt,int left,int right){
//cout<<left<<" "<<right<<endl;
if(tree[rt].mmax<=mmax&&tree[rt].mmin>=mmin) return ;//剪枝
if(tree[rt].l==left&&tree[rt].r==right){
mmax=max(mmax,tree[rt].mmax);
mmin=min(mmin,tree[rt].mmin);
return ;
}
int mid=(tree[rt].l+tree[rt].r)>>1;
if(right<=mid) query(rt<<1,left,right);//注意,在单枝树转移的时候不要算进去mid,因为mid往往是区间之外的。
else if(left>mid) query(rt<<1|1,left,right);//同理
else{
query(rt<<1,left,mid);
query(rt<<1|1,mid+1,right);
}
}
int main(){
while(scanf("%d%d",&n,&q)!=EOF){
for(int i=1;i<=n;i++){
scanf("%d",a+i);
}
build(1,1,n);
int a,b;
for(int i=0;i<q;i++){
scanf("%d%d",&a,&b);
mmax=-INF;
mmin=INF;
query(1,a,b);
//cout<<mmax<<" "<<mmin<<endl;
cout<<mmax-mmin<<endl;
}
}
return 0;
}