ST表(离线RMQ)

离线RAQ时,预处理为O(n*lgn),查询为O(1)的算法,比较有意思的一种算法

放个模板在这可以随时看

 1 //ST表(离线)
 2 //预处理 O(n*lgn) , 查询 O(1)
 3 #include <iostream>
 4 #include <stdio.h>
 5 using namespace std;
 6 #define MX 10005
 7 
 8 int n;
 9 int a[MX];
10 int st[MX][20]; // st[i][j] 是第 i 个数为左端点长为 2^j 区间的最大值
11 int lgn[MX]; //lgn[i] 是 lgn(i) 的值
12 
13 void Init()
14 {
15     lgn[0]=-1;
16     for (int i=1;i<=n;i++)
17     {
18         if ((i&(i-1))==0) lgn[i]=lgn[i-1]+1;
19         else lgn[i]=lgn[i-1];
20         st[i][0]=a[i];
21     }
22     for (int i=1;i<=lgn[n];i++) //区间长为 2^i 次方
23         for (int j=1;j+(1<<i)-1<=n;j++)
24             st[j][i]=max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
25 }
26 
27 int inquery(int a,int b)
28 {
29     int k = lgn[b-a+1];
30     return max(st[a][k],st[b-(1<<k)+1][k]);
31 }
32 
33 int main()
34 {
35     scanf("%d",&n);
36     for (int i=1;i<=n;i++)
37         scanf("%d",&a[i]);
38     Init();
39     int m;
40     scanf("%d",&m);
41     while (m--)
42     {
43         int l,r;
44         scanf("%d%d",&l,&r);
45         printf("%d\n",inquery(l,r));
46     }
47     return 0;
48 }
View Code

 

posted @ 2017-07-15 19:25  happy_codes  阅读(205)  评论(0编辑  收藏  举报