1. 程式人生 > >POJ 3264 線段樹求區間最大最小值

POJ 3264 線段樹求區間最大最小值

很裸的線段樹,沒有什麼好說的,我把根節點所擁有的左右區間都寫在結構體裡面,這樣傳參的時候比較方便。
POJ不支援萬能頭很不習慣。

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=5e4+50,inf=0x3f3f3f3f;
int a[maxn],ans1,ans2;struct node{ int l,r,maxx,minn; }s[maxn<<2];
void build(int root,int l,int r) {
	s[root].l=l,s[root].r=r,s[root].maxx=-1,s[root].minn=inf;
	if(l==r) { s[root].maxx=s[root].minn=a[l];return;}
	int mid=(l+r)>>1;
	build(root<<1,l,mid);
	build(root<<1|1,mid+1,r);
	s[root].maxx=max(s[root<<1].maxx,s[root<<1|1].maxx);
	s[root].minn=min(s[root<<1].minn,s[root<<1|1].minn);	
}
void query(int root,int l,int r) {
	if(s[root].l==l&&s[root].r==r) {ans1=max(ans1,s[root].maxx),ans2=min(ans2,s[root].minn);return;}
	int mid=(s[root].l+s[root].r)>>1;
	if(r<=mid) query(root<<1,l,r);
	else if(l>=mid+1) query(root<<1|1,l,r);
	else {
		query(root<<1,l,mid);
		query(root<<1|1,mid+1,r);
	}
}
int main()
{
	int n,m,l,r;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=1;i<=m;++i){
		scanf("%d%d",&l,&r);ans1=-1,ans2=0x3f3f3f3f;
		query(1,l,r);printf("%d\n",ans1-ans2);
	}
	return 0;
}