ST 算法

算法 专栏收录该内容
8 篇文章 0 订阅

在RMQ问题(区间最值问题) 中 , ST 算法就是倍增的产物 。给定一个长度为N的数列 A ,ST算法能在 O(NlogN) 时间的预处理后,以O(1)的时间复杂度在线回答" 数列 A 中下标在 l ~ r 之间最大的值是多少" ,这样的区间最值问题 。

设 F [i,j] 表示数列A 中下标在子区间 [i ,i+2^{j}-1]里的数的最大值 ,也就是从 i 开始的 2^{j} 个数的最大值。递推边界显然是F[i,0] = A[i]  , 即数列 A 在子区间 [ i,j ] 里的最大值 。

在递推时,我们把子区间的长度成倍的增长 ,有公式 F[i,j] = max(F[i,j-1],F[i+2^{j},j-1]) ,即长度为 2^{j} 的子区间的最大值是左右两半长度为 2^{j-1} 的子区间的最大值中的较大的一个。

// 区间最值
void ST_prework() { // st算法预处理
	for(int i = 1 ;i<=n ; i++ ) {
		f[i][0] = a[i] ; // 处理边界 [i,i] 的最大值就是 a[i]
	}
	int t = log(n)/log(2) + 1 ; // 这里是枚举右端点
	for(int j =1 ; j<t ; 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]) ;
			f[i][j] = min(f[i][j-1] ,f[i+(1<<(j-1))][j-1]) ;
		}
	}
	
}

 

当询问任意区间 [  L, R ] 的最值时, 我们先计算出一个 k  ,满足 2^{k} < r-l+1 <=2^{k+1} ,也就是使2 的k 次幂小于区间长度的前提下的最大 k 。那么, " 从 l 开始的 2^{k} 个数" 和"以 r 结尾的 2^{k}个数"这两段一定覆盖了整个区间 [ l,r ] ,这两段的最大值分别是 F[l,k] 和 F[r-2^k +1 , k] ,二者中较大的那个就是整个区间的最值。

 

int ST_query(int l ,int r){ // 查询 区间 [l,r] 之间的最值
	int k = log(r-l+1)/log(2);
	return max(f[l][k],f[r-(1<<k)+1][k]) ;
}

 

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:马嘣嘣 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值