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

你可能感兴趣的:(poj)