当前位置:网站首页>倍增和稀疏表
倍增和稀疏表
2022-08-02 14:10:00 【老顽固也可爱】
倍增、ST
、RMQ
1、倍增
任意整数均可被表示成若干个2的次幂项之和。例如:
整数5,其二进制表示为101,该二进制数从右向左第0、2位均为1,则5=2+20
整数26,其二进制表示为11010,该二进制数从右向左第1、3、4位均为1,则 26 = 2 4 + 2 3 + 2 1 26=2^4+2^3+2^1 26=24+23+21 。也就是说,2的次幂项可被拼成任一需要的值。
倍增,顾名思义就是成倍增加。若问题的状态空间特别大,则一步步递推的算法复杂度太高,可以通过倍增思想,只考察2的整数次幂位置,快速缩小求解范围,直到找到解。
2、ST
ST
(Sparse Table,稀疏表)算法采用了倍增思想,在 O ( n l o g n ) O(nlogn) O(nlogn) 时间构造一个二维表之后,可以在 O ( 1 ) O(1) O(1) 时间在线查询 [ l , r ] [l, r] [l,r] 区间的最值,有效解决 在线RMQ
(Range Minimum/Maximum Query,区间最值查询)问题。如何实现呢?
设 F [ i , j ] F[i,j] F[i,j] 表示 [ i , i + 2 j − 1 ] [i, i+2^j-1] [i,i+2j−1] 区间的最值,区间长度为 2 j 2^j 2j。
根据倍增思想,长度为 2 j 2^j 2j 的区间可被分成两个长度为 2 j − 1 2^{j-1} 2j−1 的子区间,然后求两个子区间的最值即可。
递推公式: F [ i , j ] = m a x ( F [ i , j − 1 ] , F [ i + 2 j − 1 , j − 1 ] ) F[i,j]=max(F[i,j-1], F[i+2^{j-1},j-1]) F[i,j]=max(F[i,j−1],F[i+2j−1,j−1])
2.1 ST表的创建
若 F [ i , j ] F[i, j] F[i,j] 表示 [ i , i + 2 j − 1 ] [i, i+2^{j}-1] [i,i+2j−1] 区间的最值,区间长度为 2 j 2^j 2j,则和 j j j 的取值范围是多少呢?
若数组的长度为 n n n ,最大区间长度 2 k ≤ n < 2 k + 1 2^k≤n<2^{k+1} 2k≤n<2k+1,则 k = ⌊ l o g 2 n ⌋ k=\lfloor log_2n\rfloor k=⌊log2n⌋, 比如:
- n=8时k=3,
- n=10时k=3。
在程序中,k=log2(n)
, 也可用通用表达方式 k=log(n)/log(2)
,log()
表 示以 e
为底的自然对数。
void ST_create() {
for(int i=1; i<=n; i++) {
F[i][0]=a[i];// 区间[i,i]的最值,区间长度位2^0
}
int k=log(n)/log(2.0);
for(int j=1; j<=k; j++) {
for(int i=1; i<=n-(1<<y)+1; i++) {
F[i][j]=max(F[i][j-1],F[i+(1<<j-1)][j-1])
}
}
}
例如,有10个元素 a [ 1..10 ] = 5 , 3 , 7 , 2 , 12 , 1 , 6 , 4 , 8 , 15 a[1..10]={5,3,7,2,12,1,6,4, 8,15} a[1..10]=5,3,7,2,12,1,6,4,8,15,创建查询最大值的ST表。 F [ i , j ] F[i,j] F[i,j] 表示 [ i , i + 2 j − 1 ] [i, i+2^j-1] [i,i+2j−1] 区间的最值,区间长度为2。
2.2 ST表查询
若查询 [ l , r ] [l,r] [l,r] 区间的最值,则首先计算 k k k 值,和前面的计算方法相同,区间长度为 r − l + 1 r-l+1 r−l+1, 2 k ≤ r − l + 1 < 2 k + 1 2^k\leq r-l+1<2^{k+1} 2k≤r−l+1<2k+1, 因此 $k=log2(r-l+1) $。
若查询区间的长度大于或等于 2 2 2 且小于 2 k + 1 2^{k+1} 2k+1 ,则根据倍增思想,可以将查询区间分为两个查询区间,取两个区间的最值即可。两个区间分别为从向后的 2 k 2^k 2k 个数及从 r r r 向前的 2 k 2^k 2k 个数,这两个区间可能有重叠,但对求最值没有影响。
int ST_query(int l, int r){
int k=log2(r-l+1);
return max(F[l][k], F[r-(1<<k)+1][k])
}
3、RMQ
RMQ
(区间最值查询)问题有多种解决方法,用线段树和ST解决RMQ
问题的对比如下:
- 线段树预处理的时间为 O ( n l o g n ) O(nlogn) O(nlogn),查询的时间为 O ( l o g n ) O(logn) O(logn) ,支持在线修改
- ST预处理的时间为 O ( n l o g n ) O(nlogn) O(nlogn),查询的时间为 0 ( 1 ) 0(1) 0(1) ,不支持在线修改。
边栏推荐
猜你喜欢
随机推荐
Mysql的锁
使用libcurl将Opencv Mat的图像上传到文件服务器,基于post请求和ftp协议两种方法
【我的电赛日记(一)】HMI USART串口屏
Win10电脑不能读取U盘怎么办?不识别U盘怎么解决?
DP1101兼容CC1101是SUB1GHz无线收发芯片应用于智能家居
【系统设计与实现】基于flink的分心驾驶预测与数据分析系统
source /build/envsetup.sh和lunch)
TypeScript 快速进阶
蓝牙温度检测系统(基于BT08-B蓝牙模块)
HAL框架
LORA芯片ASR6505无线远距离传输8位MCU
win10系统更新错误代码0x80244022怎么办
mysql的索引结构为什么选用B+树?
Binder机制(下篇)
发布模块到npm应该怎么操作?及错误问题解决方案
casbin模型
What should I do if the Win10 system sets the application identity to automatically prompt for access denied?
使用 腾讯云搭建一个个人博客
Mysql连接错误解决
将SSE指令转换为ARM NEON指令