ST表详解

相关概念

  • ST表,又名稀疏表,是一种基于倍增思想,用于解决可重复贡献问题的数据结构

倍增:是一种思想,顾名思义,成倍的增加。例如STL库中的vector,之所以称为动态数组,在不指定大小的情况下,初始化为1个空间,而其空间变化规律为1, 2, 4……当添加一个新元素时,如果空间不够,则空间成倍扩大,如下图所示
在这里插入图片描述

可重复贡献问题 是指对于运算op,满足 x op x = x,则对应的区间询问就是一个可重复贡献问题。
例如,最大值有 max(x,x) = x,gcd 有 gcd(x,x) = x,所以 RMQ 和区间 GCD 就是一个可重复贡献问题。

应用场景

  • ST表可用于解决RMQ问题,即区间最值问题

RMQ 是英文 Range Maximum/Minimum Query 的缩写,表示区间最大(最小)值

原理(以求最大值为例)

  • ST表中定义了一个二维数组f[N][M],f[i][j]表示区间[i, i + 2j + 1]内的最大值
  • 根据倍增思想,给出状态转移方程f[i][j] = max(f[i][j - 1], f[i + 2^j - 1^][j - 1])

f[i][j]对应区间[i, i + 2j + 1],长度为2j,若想求该区间内的最大值,则可以将该区间划分为两个等长的区间,长度均为2j / 2 = 2j-1,求每个区间的最大值,再取两者的max即可
由于不同区间有重叠部分,因此从最左侧的区间开始寻找,在后续遍历时会用到前面的结果
在这里插入图片描述
在这里插入图片描述

代码实现

ST表的创建

首先需要确定最大区间长度,以确定f[i][j]中i和j的取值范围
假设数组的长度为n,则有2k <= n < 2k+1,由此可得k = [log2(n)](以2为底n的对数,向下取整)

void ST_Init()
{
	for(int i = 1; i <= n; i ++) f[i][0] = a[i]; //f[i][j],当j为0时,区间长度2^j为0,则区间最大值就是区间的唯一元素a[i] 
	int k = log2(n); //使用math.h库的函数,计算i和j的取值范围 
	for(int j = 1; j <= k; j ++) //之前已经计算过区间长度为0的情况,这里区间长度由2^1 到 2^k 
	{
		for(int i = 1; i <= n - (1 << j) + 1; i ++) //确定区间左端点,区间范围为[i, i + 2^j - 1],所以 i + 2^j - 1 <= n
			f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]); //状态转移方程 
	}
}

时间复杂度O(nlogn)

ST表的查询

对于给定的区间[l, r],首先确定k值,区间长度为r - l + 1,则有2k <= r - l + 1 < 2k+1,再将整个区间分为前2k个数,和后2k个数,分别求出最值,再取二者的max

这里我们会发现,划分的两个区域可能会有重叠部分,如[1, 2, 5, 8, 6]划分为[1, 2, 5]和[5, 8, 6]两个部分,第一个区间最大值为5,第二个区间最大值为8,最终得到的整个区间最大值为8。由此可见,区间重叠对整个区间最大值无影响

int ST_Query(int l, int r)  
{
	int k = log2(r - l + 1);
	return max(f[l][k], f[r - (1 << k) + 1][k]);
} 

时间复杂度O(1)

相关题目

ST表模板题
附近最小

总结

ST表可在O(nlogn)的时间内,查询到给定区间的最值,速度非常快。但缺点时,该过程中,整个数组的元素不能发生变化,否则,每发生一次变化,就要进行一次初始化

欢迎大家批评指正!!!

### 回答1: ST(Sparse Table)是一种用于解决区间查询问题的数据结构。它可以支持在 O(1) 的时间复杂度内查询一个区间中的最大值、最小值、和、积等等。 ST的基本思想是利用区间重叠的性质,将区间划分成若干个长度为2的子区间,对每个子区间记录其区间内的最大值、最小值、和、积等信息。这些子区间的信息可以通过递归的方式预处理出来,构建出一张类似二维格的 ST。查询一个区间的信息时,可以通过查询两个子区间的信息并取其合并得到。 ST的构建时间复杂度为 O(n log n),其中 n 是数据的规模。查询一个区间的信息的时间复杂度为 O(1)。ST的空间复杂度为 O(n log n)。 ST常用于解决区间查询问题,例如在数组中查询一个区间的最大值、最小值、和、积等信息。同时,ST也可以用于支持动态区间查询,即在不断修改数组元素的情况下,仍然能够在 O(1) 的时间复杂度内查询任意一个区间的信息。 ### 回答2: ST,全称Sparse Table,是一种常见的数据结构,用于支持高效地查询一段区间内的最值操作。它主要用于快速处理静态的区间最值查询问题。 ST的构建过程很简单。首先,我们需要预处理一个二维数组dp,其中dp[i][j]示从位置i开始,长度为2^j的区间内的最值。这个数组的大小需要根据具体问题来确定。 接下来,我们对dp数组进行初始化。假设我们要求最小值,那么dp[i][0]就等于位置i的元素值。然后,我们可以通过以下递推公式计算出dp数组的其他元素:dp[i][j] = min(dp[i][j-1], dp[i + 2^(j-1)][j-1])。这个公式示,从位置i开始,长度为2^j的区间内的最值等于从位置i开始,长度为2^(j-1)的两个子区间的最值之间的较小值。 构建好dp数组后,我们就可以通过查询来快速得到区间的最值了。对于一个查询操作,我们只需要找到最小的k,使得2^k大于等于查询区间的长度。然后,我们可以通过以下递推公式计算出查询结果:min(dp[left][k], dp[right - 2^k + 1][k])。其中,left和right分别示查询区间的左右边界。 ST的时间复杂度主要来自于构建dp数组的过程,为O(nlogn),其中n为数据的长度。查询的时间复杂度为O(1),因为我们只需要进行常数次操作即可得到结果。 总结来说,ST是一种用于高效查询区间最值的数据结构。它通过预处理和递推的方式构建二维数组,可以快速回答各种区间最值查询问题。它的时间复杂度比较低,适用于快速查询静态数据的场景。 ### 回答3: ST是一种可以高效求解多种区间查询问题的数据结构。ST全称为Sparse Table,它通过预处理输入序列建立一个二维格,用于快速回答各种区间查询问题。 在ST中,将序列中的每个元素作为第0层,每个区间的最小值或最大值作为第1层,第2层是第1层区间的最小值或最大值,以此类推,直到第log(n)层。其中n是输入序列的长度。 ST的构建是通过动态规划的思想来完成的。假设有一个区间[a, b],查询区间的长度为query_len,则可以将该查询区间分为两个长度为query_len/2的子区间[a, a+query_len/2-1]和[a+query_len/2, b]。通过之前已经计算到的结果,可以很快得到子区间的最小值或最大值,然后将两个子区间的最小值或最大值作为该查询区间的结果。这样,将自顶向下地计算每个查询区间的结果,即可构造出整个STST的查询是通过将查询区间拆解成若干个长度为2的幂次的小区间,然后对应每个小区间查询结果进行合并得到的。例如,查询区间[a, b]可以拆解成多个小区间,分别是[a, a+2^k-1]、[a+2^k, a+2^(k+1)-1]、…、[b-2^k+1, b],其中k是满足2^k <= b-a+1的最大整数。然后对于每个小区间,在ST中查找得到最小值或最大值,再通过合并获得整个查询区间的结果。 ST的构建时间复杂度为O(n log(n)),其中n是输入序列的长度。每次查询的时间复杂度为O(1)。ST适用于各种区间查询问题,如最小值、最大值、和、乘积等。但只适用于静态问题,即查询的区间不会发生改变。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值