离线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 ",inquery(l,r)); 46 } 47 return 0; 48 }