当前位置:网站首页>倍增和稀疏表
倍增和稀疏表
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) ,不支持在线修改。
边栏推荐
- TCP三次握手、四次挥手
- Win11 keeps popping up User Account Control how to fix it
- FP6195耐压60V电流降压3.3V5V模块供电方案
- STM32LL库——USART中断接收不定长信息
- flink+sklearn——使用jpmml实现flink上的机器学习模型部署
- Golang 垃圾回收机制详解
- Win10 cannot directly use photo viewer to open the picture
- 系统线性、时不变、因果判断
- What should I do if I install a solid-state drive in Win10 and still have obvious lags?
- FP7195芯片PWM转模拟调光至0.1%低亮度时恒流一致性的控制原理
猜你喜欢

A clean start Windows 7?How to load only the basic service start Windows 7 system

Spark及相关生态组件安装配置——快速回忆

What is Win10 God Mode for?How to enable God Mode in Windows 10?

Mysql连接错误解决

STM32LL库使用——SPI通信

Win11系统找不到dll文件怎么修复

Do Windows 10 computers need antivirus software installed?

How to solve Win11 without local users and groups

MATLAB制作简易小动画入门详解

推开机电的大门《电路》(二):功率计算与判断
随机推荐
pygame draw arc
yolov5官方代码解读——前向传播
【我的电赛日记(三)】STM32学习笔记与要点总结
TCP三次握手、四次挥手
推开机电的大门《电路》(二):功率计算与判断
Configure clangd for vscode
轻量化AlphaPose
Win7 encounters an error and cannot boot into the desktop normally, how to solve it?
FP7195转模拟恒流调光芯片在机器视觉光源的应用优势
What should I do if Windows 10 cannot connect to the printer?Solutions for not using the printer
7. How to add the Click to RecyclerView and LongClick events
Win10电脑需要安装杀毒软件吗?
STM32F1和F4的区别
Detailed explanation of RecyclerView series article directory
Win10上帝模式干嘛的?Win10怎么开启上帝模式?
使用npx -p @storybook/cli sb init安装失败,手把手搭建专属的storybook
pygame图像连续旋转
Win10无法连接打印机怎么办?不能使用打印机的解决方法
Please make sure you have the correct access rights and the repository exists.问题解决
STM32LL库使用——SPI通信