想看更多的解题报告: 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;
}