RMQ问题之ST算法

时间:2019-01-31
本文章向大家介绍RMQ问题之ST算法,主要包括RMQ问题之ST算法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
  1. ST算法
    ST算法是用于解决RMQ问题(区间最值问题)的一种强有力的工具。
    O(nlogn)预处理,O(1)查询最值,利用的是倍增的思想。
    但…但是,使用ST算法的条件是没有修改操作,emmm
  2. 算法流程(最大值为例)
    ①预处理
    用f[i][j]表示,从i位置开始的2^j 个数中的最大值,例如f[i][j]表示的是a[i][i+2^j-1]这个区间的最大值。
    转移的时候我们可以把当前区间拆成两个区间并分别取最大值。
    f[i][j]分为f[i][j-1]和f[i+2^(j-1)][j-1]
    ②询问
    询问左端点l,右端点r;
    k=log2(r-l+1)
    然后对于左端点和右端点分别进行查询,这样可以保证一定可以覆盖查询的区间。
    左端点查询区间[l,l+2^k-1]
    右端点查询区间[r-2^k+1,r]
    讲的可能比较抽象,可以画个图好好理解一下
  3. 代码实现
    代码就比较好理解了,需要注意的:1.加减乘除的优先级高于位运算 2.双重循环外层是j,下面附模板ST算法代码
const int maxn=1e5+5;
int n,m,x,y;
int a[maxn],f[maxn][21];
int query(int l,int r)
{
	int k=log2(r-l+1);
	return max(f[l][k],f[r-(1<<k)+1][k]);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(R i=1;i<=n;++i)	scanf("%d",&a[i]);
	for(R i=1;i<=n;++i)
		f[i][0]=a[i];
	for(R j=1;j<=21;++j)//计算f[i][j],外层j! 
		for(R i=1;i+(1<<j)-1<=n;++i)//边界条件 
			f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);//加减优先级高于位运算 
	while(m--)
	{
		scanf("%d%d",&x,&y);
		printf("%d\n",query(x,y));
	}
	return 0;	
} 
  1. 就快是猪年啦,提前祝新年快乐,菜鸡新年也要继续加油鸭