ST算法—介绍

ST算法是解决RMQ(区间最值)问题,它能在O(nlogn)的时间预处理,然后O(1)回答。

其原理是倍增f[i][j]表示从i位起的2^j个数中的最大数,即[i,i+2^j-1]中的最大值,从其定义中可以看出来。


下面直接介绍它的预处理过程。

f[i][0]表示[i,i]中的最大值,只能是a[i],故f[i][0]=a[i]。

对于任意的f[j][i],我们分成两段相等长度的数列来看,[j,j+2^(i-1)-1]和[j+2^(i-1),j+2^i-1],分别对应f[j][i-1]和f[j+(1<


查询是O(1)解决的,难道真的可以用一个式子求出区间[l,r]的最大值?没错!
虽然我们预处理出来的f很难恰好覆盖[l,r],但是我们可以用两个f来覆盖[l,r],这个覆盖不要求做到不重,只要不漏就可以了(很好理解吧)。既然可以重复,我们只要控制好不要超出[l,r]就好了。
先确定一个长度2^k,其中k=log2(r-l+1)。这个长度2^k保证小于等于r-l+1,因为k是向下取整的。
接着以l为起始点,往右查询,即f[l][k];再以r为结束点,往左查询,即f[r-(1<

最后,把两者比较一下,其最大值就是[l,r]中的最大值。


例题(洛谷3865 【模板】ST表)

给定一个长度为 N 的数列,和 M 次询问,求出每一次询问的区间内数字的最大值。


代码

#include
#include
#include
#include
using namespace std;
const int maxn=1e5+10;


int n,m;
int a[maxn];
int f[maxn][20];//f[i][j]表示从i位起的2^j个数中的最大数,即[i,i+(1<


你可能感兴趣的:(倍增,ST算法,《算法竞赛进阶指南》刷书之旅)