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