目录
一.前置内容(倍增思想)
- 定义:每次通过倍增加速状态转移、预处理或查询(很多时候能把时间复杂度降到O(logN))
解释一下:任意整数均可以被表示成若干个2的次幂之和即二进制。倍增就是成倍增加,若问题的状态空间特备大,则一步步的递推算法复杂度太高,可以通过倍增的思想,只考虑2的整数次幂位置,快速缩小求解范围直到找到解。
实际应用:动态数组,稀疏表,后缀数组,快速幂等等很多问题的解决都是用的倍增思想。
举个栗子:比如在一颗树中查找一个数x,这是一颗父节点比子节点大的树
每次可以以2的次幂形式往上查找。
二.稀疏表的定义
稀疏表可以在O(1)时间在线查询【l,r】区间的最值问题。
定义F【i,j】i是区间的起始位置,区间长度为
可以得出递推公式
三.稀疏表的建立(含C详解代码)
1.我们先考虑一下i和j的取值范围
若数组长度为n,最大区间长度,最大区间长度那么k是
比如:n = 16,k = 4。n = 20, k = 4
代码实现求解k
得出j的范围是【1,k】,i的范围是【1,】
代码实现:时间复杂度O(nlogn)
我举个栗子画个图直观感受下:
例如a[1...10] = {5,3,7,2,12,1,6,4,8,15}创立的稀疏表为
例如:F[1][3]就是从1开始长度为8的区间最大值
四.稀疏表的查询
此时已经建立了稀疏表,假设查询【L,R】区间最值,则首先需要计算区间长度,区间长度为
然后转化为2次幂的形式
根据倍增思想,我们将查询区间分为两个查询区间,取两个区间的最值即可。
那该如何划分区间呢?
分别从L向后的个数和从R向前的个数
代码实现:时间复杂度O(1)
五.总结
稀疏表Sparse Table不支持在线修改,因为修改后要推翻原先已经建立的ST表。
RMQ问题就是区间最值查询(range max/min query)有多种解决办法,用线段树和ST解决都可以
区别如下: