RMQ的st表算法

时间:2023-03-08 17:46:03

此算法可用来处理区间最值问题,预处理时间为O(nlogn),查询时间为O(1)

此算法主要基于倍增思想,用以数组st[i][j]表示从第i个元素开始向后搜2的j次方的最值

可用递推的方式求得:st[i][j]=min/max(st[i][j-1],st[i+1<<(j-1)][j-1])

下面的模板以区间最大值为例

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int st[100010][22];
int a[100010];
int main()
{     int n,m,i,j,k,x,y;
      scanf("%d%d",&n,&m);
      for(i=1;i<=n;i++){
          scanf("%d",&a[i]);
          st[i][0]=a[i];
      }
      for(j=1;(1<<j)<=n;j++)
         for(i=1;i+(1<<j)-1<=n;i++){
             st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
         }
      for(i=1;i<=m;i++){
          scanf("%d%d",&x,&y);
          k=0;
          while((1<<(k+1))<=y-x+1)k++;
          printf("%d\n",max(st[x][k],st[y-(1<<k)+1][k]));

//注意要用括号把1<<k括起来,否则会wa

//注意加一
      }
      return 0;
}