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