poj3264_RMQ_ST

这个题昨天做过,但是今天使用的是RMQ_ST算法,网上关于RMQ还有中笛卡尔树的算法,今天我用的是ST算法,这个算法很给力,在初始化之后可以在O(1)的时间内求出最大值和最小值。

先简要介绍一下ST算法,ST算法需要辅助数组f[i][j]表示从第i个元素开始连续2^j个元素中的最大值(这里以最大值举例),有:

1.初始 f[i][0]=a[i]

2.对于f[i][j] j>0 有f[i][j]=max( f[i][j-1] , f[i+2^(j-1)][j-1] ),当然每次比较之前必须保证i+2^(j-1)<=n中

在初始化的过程中 j:1--m 这样保证f[1][1]=max(f[1][0],f[2][0])被比较的两个对象已经赋值,其中m=log(n)/log(2.0)

然后就可以在o(1)的时间对所给的区间(s,e)找出最大值了,这里需要将(s,e)分成两个长度为2^n的区间,这两个区间跟f[]相对应

中间值k=log(e-s+1)/log(2)

res=max(f[s][k],f[e-2^k+1][k])

以下是RMQ_ST的代码:

View Code
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <math.h>
 4 using namespace std;
 5 
 6 const int maxnum=50005;
 7 int f[maxnum][15+1];  //max数组
 8 int g[maxnum][15+1];  //min数组
 9 int a[maxnum];
10 int n,q;
11 
12 void RMQInit()
13 {
14     int i;
15     for(i=1;i<=n;i++)
16     {
17         f[i][0]=a[i];
18         g[i][0]=a[i];
19     }
20 
21     int m=log((double)maxnum)/log((double)2);
22     int j;
23     for(j=1;j<=m;j++)
24         for(i=1;i<=n;i++)
25         {
26             f[i][j]=f[i][j-1];
27             if( i+(1<<(j-1)) <= maxnum)   //+的优先级比<<要高,所以得加括号
28                 f[i][j]=f[i][j]>=f[i+(1<<(j-1))][j-1]?f[i][j]:f[i+(1<<(j-1))][j-1];
29 
30             g[i][j]=g[i][j-1];
31             if(i+(1<<(j-1))<=maxnum)
32                 g[i][j]=g[i][j]<=g[i+(1<<(j-1))][j-1]?g[i][j]:g[i+(1<<(j-1))][j-1];
33         }
34 }
35 
36 int RMQ_Max(int s,int e)
37 {
38     int k;
39     k=log((double)(e-s+1))/log((double)2);   //+1
40     return f[s][k]>=f[e-(1<<k)+1][k]?f[s][k]:f[e-(1<<k)+1][k];  //这里左移的都是1
41 
42 }
43 
44 int RMQ_Min(int s,int e)
45 {
46     int k;
47     k=log((double)(e-s+1))/log((double)2);  //+1
48     return g[s][k]<=g[e-(1<<k)+1][k]?g[s][k]:g[e-(1<<k)+1][k];
49 
50 }
51 
52 int main()
53 {
54     scanf("%d%d",&n,&q);
55     int i;
56     for(i=1;i<=n;i++)
57         scanf("%d",&a[i]);
58     RMQInit();
59 
60     int s,e;
61     for(i=1;i<=q;i++)
62     {
63         scanf("%d%d",&s,&e);
64         printf("%d\n",RMQ_Max(s,e)-RMQ_Min(s,e));
65     }
66     return 0;
67 }

这个题也是tju oj的2762

posted @ 2012-07-12 19:10  pushing my way  阅读(205)  评论(0编辑  收藏  举报