poj3264 - Balanced Lineup

                                    想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
                                     转载请注明出处:
http://blog.csdn.net/wangjian8006

题目大意:给出一串的数字,然后给出一个区间a b,输出从a到b的最大的数和最小的数的差

解题方法:线段树

用线段树求出从a到b的最小值与最大值,直接相减输出就可以了

#include <iostream>
using namespace std;
#define MAXV 50100
#define MAXT 1<<18
#define max(a,b) a>b?a:b
#define min(a,b) a>b?b:a

int a[MAXV],TL[MAXT],TR[MAXT],TMAX[MAXT],TMIN[MAXT];
//TL与TR代表结点v区间的左边与右边的数,这样方便查询
//TMAX,TMIN,代表结点v的最大值与最小值

void createTree(int v,int f,int t){
	TL[v]=f;
	TR[v]=t;
	if(f==t){
		TMAX[v]=a[f];
		TMIN[v]=a[f];
		return;
	}

	int mid=(f+t)>>1;
	createTree(v<<1,f,mid);
	createTree((v<<1)|1,mid+1,t);

	TMAX[v]=max(TMAX[v<<1],TMAX[(v<<1)|1]);
	TMIN[v]=min(TMIN[v<<1],TMIN[(v<<1)|1]);
}
int queryTree(int v,int L,int R,int flag){
	if(L==TL[v] && R==TR[v]){
		return (flag?TMIN[v]:TMAX[v]);
	}

	int mid=(TL[v]+TR[v])>>1;
	if(R<=mid)
		return queryTree(v<<1,L,R,flag);
	else if(L>mid)
		return queryTree((v<<1)|1,L,R,flag);
	else{
		if(flag) return min(queryTree(v<<1,L,mid,flag),queryTree((v<<1)|1,mid+1,R,flag));
		else return max(queryTree(v<<1,L,mid,flag),queryTree((v<<1)|1,mid+1,R,flag));
	}
}

int main(){
	int N,Q,L,R,i;
	while(scanf("%d%d",&N,&Q)!=EOF){
		for(i=1;i<=N;i++)
			scanf("%d",&a[i]);

		createTree(1,1,N);
		while(Q--){
			scanf("%d%d",&L,&R);
			printf("%d\n",queryTree(1,L,R,0)-queryTree(1,L,R,1));
		}
	}
	return 0;
}


 

你可能感兴趣的:(poj3264 - Balanced Lineup)