观前说明:作者菜 无条件接受所有正常建议 轻喷
写作目的:发现ACGO好像没有较为详细地有关ST表的文章 最近刚好在学 觉得写这个帮助清晰思路 就写了
注释:本文有参考xiaoshumiao(洛谷)的ST表,天泽龟(洛谷)的P3865 【模板】ST 表 && RMQ 问题 题解 和 进阶算法思想(洛谷课程)
前置:
1.小学语文,数学知识(不提供讲解):
如:22i2^{2^i}22i=22∗2i−12^{2*2^{i-1}}22∗2i−1
2.二进制分解思想:
以2020 CSP-J T1:优秀的拆分为例:
888=232^323
888的二进制:1000
18=21+2418=2^1+2^418=21+24
181818的二进制:10010
正文开始:
1.应用:用于快速求出区间内最小/最大值的数据结构
2.思想:利用倍增思想(来缩短时间)
倍增思想:
倍增是基于二进制分解思想的预处理算法.
*二进制分解思想:具体参考2020 CSP-J T1:优秀的拆分
倍增主要用于优化树结构中的跳跃路径查询问题
操作方式:记录每个节点向上跳跃2j2^j2j层的祖先节点
而在ST表中,倍增思想的体现在于其数组的定义
似乎比较难懂.可以再看这题倍增快速幂
这道题主要是求aba^bab:
b使用二进制拆分:b=b0+b1+b2...+bnb_0+b_1+b_2...+b_nb0 +b1 +b2 ...+bn
*这里的每一个bib_ibi 都已二次方形式表现 也就是2i2^i2i
由此,最后需要求的aba^bab变成:
ab0∗ab1∗ab2∗...∗abna^{b_0}*a^{b_1}*a^{b_2}*...*a^{b_n}ab0 ∗ab1 ∗ab2 ∗...∗abn
设f(i)f(i)f(i)为a2ia^{2^{i}}a2i 也可以转变为a2∗2i−1a^{2*2^{i-1}}a2∗2i−1 也就是f(i−1)2f(i-1)^2f(i−1)2 (回收开头之小学数学知识)
那么,需要转换的aba^bab变成:
f(i0)∗f(i1)∗f(i2)∗f(i3)∗......f(in)f(i_0)*f(i_1)*f(i_2)*f(i_3)*......f(i_n)f(i0 )∗f(i1 )∗f(i2 )∗f(i3 )∗......f(in )
*这里的i0,i1,i2,i3i_0,i_1,i_2,i_3i0 ,i1 ,i2 ,i3 等没有特定的数值.它们的数值取决于b0,b1,b2,b3b_0,b_1,b_2,b_3b0 ,b1 ,b2 ,b3 是多少:
ixi_xix =log2(bx)log_2(b_x)log2 (bx )
似乎更难懂了
代入几个数值:
a=3 , b=5
b=20+222^0+2^220+22
353^{5}35=320∗3223^{2^{0}}*3^{2^{2}}320∗322
353^{5}35=f(0)+f(2)f(0)+f(2)f(0)+f(2)
f(0)=320=31=3f(0)=3^{2^0}=3^1=3f(0)=320=31=3
f(1)=f(0)2=3∗3=9f(1)=f(0)^2=3*3=9f(1)=f(0)2=3∗3=9
f(2)=f(1)2=9∗9=81f(2)=f(1)^2=9*9=81f(2)=f(1)2=9∗9=81
35=3∗81=2433^5=3*81=24335=3∗81=243
此次代入数值的成果:
1.理清思路
2.明白需要初始化:f(0)f(0)f(0)不可能从f(−1)f(-1)f(−1)来
3.明白f(i)f(i)f(i)并不是连续的,但是从i0i_0i0 到ini_nin 的每一个f(ix)f(i_x)f(ix )都需要求出,尽管它们中有一部分不需要(但为了求它们的后续值,依然需要将它们求出)
丑陋代码:
然后,可以观察一下本题的时间复杂度:如果说,直接乘b次a的话,时间复杂度是O(b)O(b)O(b) 但是(似乎是)使用了倍增后,它的时间复杂度降到了O(logn)O(log n)O(logn)
3.实现:(此处从P3865 【模板】ST 表 && RMQ 问题入手)
这道题分为两个阶段:预处理阶段&求最值阶段
一.预处理阶段
这里的"预处理"指的是使用一个二维数组f,存储所有区间的最值.
fi,pf_{i,p}fi,p 表示以p为左端点,长度为2i2^i2i的区间的最大值.(回收上文倍增思想的体现)
考虑2i2^i2i=22∗2i−12^{2*2^{i-1}}22∗2i−1这个式子(回收开头).长度为2i2^i2i的区间可拆成两个长度为2i−12^{i-1}2i−1次方的小区间.
第一个区间的端点为p,第二个区间的端点为p+2i−1p+2^{i-1}p+2i−1.
递推式:fi,p=max(fi−1,p,fi−1,p+2i−1)f_{i,p}=max(f_{i-1,p},f_{i-1,p+2^{i-1}})fi,p =max(fi−1,p ,fi−1,p+2i−1 )