数据结构之ST表
ST表
一、是什么?:
它是解决RMQ问题(区间最值问题)的一种强有力的工具(静态区间最大值);
二、原理:
把给定区间分成长度是2的幂次的小区间。先预处理出它们中的最小值是多少,然后用一种类似二分的思想由小区间到大区间比较两个区间的最小值;
三、操作:
预处理:建一个数组f[i][p]表示[i,i+(1<<p)-1]区间最大值;递推构建;
【O(nlogn)】
查询:若查询[l,r]的区间最值,找到小于等于l-r+1的最大的2的k次方,记2的k次方为len;
那个[l,r]的区间最值等价于[l,l+len-1]与[r-len+1,r]中的最值;
【O(1)】
#include<iostream> #include<cmath> #include<algorithm> #include<cstdio> using namespace std; const int M=1e5+10; int f[M][40],LOG,l,r,n,m,p,a; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a); f[i][0]=a; } LOG=(int)(log(n)/log(2));//找到小于数据长度2的最大LOG次方 for(int j=1;j<=LOG;j++) for(int i=1;i<=n-(1<<j)+1;i++) f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); //由2的j-1次方区间长度的最大值向2的j次方的区间更新 for(int i=1;i<=m;i++){ scanf("%d%d",&l,&r); p=(int)(log(r-l+1)/log(2)); //找到小于访问区间长度的2的最大p次方 printf("%d\n",max(f[l][p],f[r-(1<<p)+1][p])); //假如2的p次方为len,取[l,l+len-1]与[r-len+1,r]中较大的那个 //区间覆盖会重叠,但不影响区间最大值 } return 0; }