poj3264 -- Balanced Lineup 一维RMQ 线段树
求区间最大值与最小值的差,最经典的是RMQ,线段树也能做,第一次写线段树,庆祝^_^
线段树代码:
View Code
1 //Accepted 1200K 2094MS C++ 1633B 2 #include <stdio.h> 3 #include <string.h> 4 5 #define lson l , m , rt << 1 6 #define rson m + 1 , r , rt << 1 | 1 7 const int maxn = 55555; 8 9 int st_min[maxn<<2],st_max[maxn<<2]; 10 11 inline int minn(int a,int b) { return a>b?b:a; } 12 inline int maxx(int a,int b) { return a>b?a:b; } 13 14 void PushUP(int rt) 15 { 16 st_min[rt] = minn(st_min[rt<<1],st_min[rt<<1|1]); 17 st_max[rt] = maxx(st_max[rt<<1],st_max[rt<<1|1]); 18 } 19 20 void build(int l,int r,int rt) { 21 if (l == r) 22 { 23 scanf("%d",&st_min[rt]); 24 st_max[rt] = st_min[rt]; 25 return ; 26 } 27 int m = (l + r) >> 1; 28 build(lson); 29 build(rson); 30 PushUP(rt); 31 } 32 33 void update(int p,int add,int l,int r,int rt) { 34 if (l == r) 35 { 36 st_min[rt] += add; 37 st_max[rt] += add; 38 return ; 39 } 40 int m = (l + r) >> 1; 41 if (p <= m) update(p , add , lson); 42 else update(p , add , rson); 43 PushUP(rt); 44 } 45 46 int query_min(int L,int R,int l,int r,int rt) 47 { 48 if (L <= l && r <= R) { 49 return st_min[rt]; 50 } 51 int m = (l + r) >> 1; 52 int ret1 = 1000010,ret2 = 1000010; 53 if (L <= m) ret1 = query_min(L , R , lson); 54 if (R > m) ret2 = query_min(L , R , rson); 55 return minn(ret1,ret2); 56 } 57 58 int query_max(int L,int R,int l,int r,int rt) 59 { 60 if (L <= l && r <= R) { 61 return st_max[rt]; 62 } 63 int m = (l + r) >> 1; 64 int ret1 = -1,ret2 = -1; 65 if (L <= m) ret1 = query_max(L , R , lson); 66 if (R > m) ret2 = query_max(L , R , rson); 67 return maxx(ret1,ret2); 68 } 69 70 int main(void) 71 { 72 int n,a,b,m; 73 while(scanf("%d%d",&n,&m)!=EOF) 74 { 75 build(1 , n , 1); 76 while(m--) 77 { 78 scanf("%d%d",&a,&b); 79 printf("%d\n",query_max(a,b,1,n,1)-query_min(a,b,1,n,1)); 80 } 81 } 82 return 0; 83 }
RMQ代码:
View Code
1 #include <cstdio> 2 #include <string> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const int MAX = 51000; 7 const int LOGMAX = 16; 8 int n; 9 int st_max[LOGMAX][MAX],st_min[LOGMAX][MAX]; 10 inline int minn(int a,int b){ return a>b?b:a; } 11 inline int maxx(int a,int b){ return a>b?a:b; } 12 void make_st() 13 { 14 int i,j,k; 15 for(j=1;(1<<j)<=n;j++) 16 { 17 k = 1 << (j-1); 18 for(i=0;i+k<n;i++) 19 { 20 st_max[j][i] = maxx(st_max[j-1][i],st_max[j-1][i+k]); 21 st_min[j][i] = minn(st_min[j-1][i],st_min[j-1][i+k]); 22 } 23 } 24 } 25 26 int rmq(int a,int b,int flag) 27 { 28 int k; 29 k=floor(log((double)(b-a+1))/log(2.0)); 30 if(flag > 0) 31 { 32 return maxx(st_max[k][a],st_max[k][b-(1<<k)+1]); 33 } 34 else 35 { 36 return minn(st_min[k][a],st_min[k][b-(1<<k)+1]); 37 } 38 } 39 40 int main(void) 41 { 42 int a,b,i,q; 43 while(scanf("%d %d",&n,&q)!=EOF) 44 { 45 for(i=0;i<n;i++) 46 { 47 scanf("%d",&st_max[0][i]); 48 st_min[0][i] = st_max[0][i]; 49 } 50 make_st(); 51 for(i=0;i<q;i++) 52 { 53 scanf("%d %d",&a,&b); 54 printf("%d\n",rmq(a-1,b-1,1)-rmq(a-1,b-1,-1)); 55 } 56 } 57 return 0; 58 }