Balanced Lineup POJ - 3264 (线段树 区间最值查询)

注意:多组输入,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;
}

 多么优美的线段树啊!

猜你喜欢

转载自blog.csdn.net/weixin_42104573/article/details/94719139