ST表
st表
ST表是什么:
ST表类似树状数组,线段树这两种算法,是一种用于解决RMQ(Range Minimum/Maximum Query,即区间最值查询)问题的离线算法与线段树相比,预处理复杂度同为O(nlogn),查询时间上,ST表为O(1),线段树为O(nlogn),st表的主体是一个二维数组st[i][j],表示需要查询的数组的从下标i到下标i+2^j - 1的最值。
ST表涉及思想:
倍增,递推。
ST表怎么实现:
用倍增的方法与递推式,预处理出第i个数分别到第i+2^j-1个数的极值,用一二维数组ex[i][j]表示。递推式为ex[i][j]=max(ex[i][j-1],ex[i+(1<<j-1)][j-1]),为之后查询时提供需要的数据。在查询时,查询区间为l—r,一般思路是:r=l+2^z-1,则ans=ex[l][l+2^z]。但往往事与愿违,r大部分情况还是l+2^z-1以外的东西。不过数据处理一下即可。
ST表查询的数据处理:
在查询l—r的过程中,我们可用两段小的区间进行合并,用什么呢?[l—l+2^k]与[r-2^k+1—r],明显这两段的最小值是预处理过的,且两区间加起来正好是询问区间。所以ans=max(ex[l][k],ex[r-(1<<k)+1][k]),其中int k=log2(r-l+1),这样k自动向下取整,保证区间不会越界且正好合适。
最后是代码:
#include<cmath> #include<cstdio> #include<iostream> #define re register using namespace std; static const int N=1e6+5; int ex[N][22]; int n,m,a; inline int query(int l,int r){ int k=log2(r-l+1); return max(ex[l][k],ex[r-(1<<k)+1][k]); } int main(){ scanf("%d%d",&n,&m); for(re int i=1;i<=n;i++){ scanf("%d",&a); ex[i][0]=a; } for(re int j=1;j<=20;j++){ for(re int i=1;i<=n-((1<<j)-1);i++){ ex[i][j]=max(ex[i][j-1],ex[i+(1<<j-1)][j-1]); } } for(re int i=1;i<=m;i++){ int l,r; scanf("%d%d",&l,&r); printf("%d\n",query(l,r)); } return 0; }


浙公网安备 33010602011771号