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 }

转载于:https://www.cnblogs.com/asen32/archive/2012/08/23/2652285.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值