题意 :N头奶牛,Q次询问,然后给你每一头奶牛的身高,每一次询问都给你两个数,x y,代表着从x位置上的奶牛到y位置上的奶牛身高最高的和最矮的相差多少。
思路 : 刚好符合RMQ的那个求区间最大最小值,所以用RMQ还是很方便的。就是一个RMQ的模板题,基本上书上网上都有。
#include <stdio.h> #include <string.h> #include <math.h> #include <iostream> const int maxn = 51000 ; int maxsum[maxn][20],minsum[maxn][20] ; int a[maxn] ; int N,Q ; using namespace std ; void Init() { for(int i = 1 ; i <= N ; i++) { scanf("%d",&a[i]) ; maxsum[i][0] = a[i] ; minsum[i][0] = a[i] ; } } void RMQ() { int k = (int )(log((double)N)/log(2.0)) ; for(int j = 1 ; j <= k ; j++) for(int i = 1 ; i <= N ; i++) if(i + (1 << j) - 1 <= N ) { maxsum[i][j] = max(maxsum[i][j-1],maxsum[i + (1 << (j-1))][j-1]) ; minsum[i][j] = min(minsum[i][j-1],minsum[i + (1 << (j-1))][j-1]) ; } } int main() { while(~scanf("%d %d",&N,&Q)) { Init() ; RMQ() ; int x,y ; for(int i = 1 ; i <= Q ; i++) { scanf("%d %d",&x,&y) ; int k = (int)(log((double)(y-x+1))/log(2.0)) ; int minn = min(minsum[x][k],minsum[y-(1<<k)+1][k]) ; int maxx = max(maxsum[x][k],maxsum[y-(1<<k)+1][k]) ; printf("%d\n",maxx-minn) ; } } return 0 ; }
线段树写法 :
1 //POJ 3264 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 6 using namespace std ; 7 8 //int maxx,minn ; 9 int p[50010 * 4],q[50010 * 4]; 10 11 void pushup(int rt) 12 { 13 p[rt] = max(p[rt << 1],p[rt << 1 | 1]) ; 14 q[rt] = min(q[rt << 1],q[rt << 1 | 1]) ; 15 } 16 void build(int l,int r,int rt) 17 { 18 int a ; 19 if(l == r) 20 { 21 scanf("%d",&a) ; 22 p[rt] = a ; 23 q[rt] = a ; 24 return ; 25 } 26 int mid = (l+r) >> 1; 27 build(l,mid,rt << 1) ; 28 build(mid+1,r,rt << 1 | 1) ; 29 pushup(rt) ; 30 } 31 int query(int L,int R,int l,int r,int rt) 32 { 33 int maxx = -1 ; 34 if(l >= L && r <= R) 35 { 36 return p[rt] ; 37 } 38 int mid = (l+r) >> 1 ; 39 if(mid >= L) 40 maxx = max(maxx,query(L,R,l,mid,rt << 1) ) ; 41 if(mid < R) 42 maxx = max(maxx,query(L,R,mid+1,r,rt << 1 | 1)) ; 43 return maxx ; 44 } 45 int querz(int L,int R,int l,int r,int rt) 46 { 47 int minn = 99999999 ; 48 if(l >= L && r <= R) 49 { 50 return q[rt] ; 51 } 52 int mid = (l+r) >> 1 ; 53 if(mid >= L) 54 minn = min(minn,querz(L,R,l,mid,rt << 1) ) ; 55 if(mid < R) 56 minn = min(minn,querz(L,R,mid+1,r,rt << 1 | 1) ); 57 return minn ; 58 } 59 int main() 60 { 61 int N,M ; 62 while(~scanf("%d %d",&N,&M)) 63 { 64 build(1,N,1) ; 65 int a,b ; 66 for(int i = 0 ; i < M ; i++) 67 { 68 scanf("%d %d",&a,&b) ; 69 // printf("%d %d*\n",query(a,b,1,N,1),querz(a,b,1,N,1)) ; 70 printf("%d\n",query(a,b,1,N,1) - querz(a,b,1,N,1) ) ; 71 } 72 } 73 return 0 ; 74 }