ST表
ST表,这是一个好东西。可以用来查询区间最值,但是不可以进行修改。
它可以做到 O(nlog(n)) 预处理,O(1) 查询。
前置知识:倍增,dp。
ST 表的优点就在于他可以用倍增来优化预处理的时间。
以模板为例。
【模板】ST 表
设 dp[i][j] 表示第 i 个数,[i,i+2j−1] 内的最大值。
考虑转移,对于当前的区间最大值,可以由两个小区间组合而成。
比如,如图中 dp[1][2] 即可由 max(dp[1][1],dp[3][1]) 转移得到。
( [1,4] 由 [1,2] 和 [3,4] 合成)。
所以,转移的时候我们可以写成:
dp[i][j]=max(dp[i][j−1],dp[i+2j−1][j−1])
然后,这就是类似一个区间 dp 的过程,然后要考虑边界:
假设当前区间长度为 12,i=6,j=3 的时候,表示的区间是 [6,6+8],就不正确了。实际上,在 j=3 的时候,i 只可以取到 [1,5(12−23+1)] 。
所以不难得出,i 的边界在 [1,12−2j+1] 中。
关于求 j,我们知道 2j≤n,j≤log(n),用 log2 函数即可。
以上部分是预处理,时间复杂度 O(nlog(n))。
现在就到了求最值。
假设我们需要求 [l,r] 的最值,就是把两个 ST 表可以直接维护的小区间,合并成这个区间的最大值。
对于起始点,我们找一个ST 表内可以覆盖的最大区间,即 log(r−l+1),记为 k ,这一段就是 dp[l][k]。
由于 dp[l][k] 不一定可以覆盖完整个区间,我们还需要一个 dp[r−2k+1][k],( k 可以覆盖的区间是 [L,L+2k−1],大小是 2k,所以就会剩下 r−2k 的数未被覆盖。而 dp[r−2k+1][k] 正好可以覆盖这部分的数)。
所以就可以 O(1) 的求了。
ans=max(dp[l][k],dp[r−2k+1][k]
其中,2i 可以写成 (1<<i) 加快速度。
Code
P2880 [USACO07JAN] Balanced Lineup G
练手题,维护当前区间的最大值和最小值即可。
Code
P4392[BOI2007]Sound 静音问题
SP7739 BOI7SOU - Sound
做法和上面略同,不再赘述,可以练手。
当然,各位要注意的是,ST 表 只是一个数据结构,对于一个静态区间的题目而言,他只是一个工具,对一道题而言,只有想到怎么样转换,才是有意义的。
CF1548B
ST表+二分解决静态区间GCD 问题。
首先看到同余,转成求 gcd 的方法就是,差分。
根据余数的可减性,可以知道,求出 gcd 即可,即可同余。
这就转换成了求一个 gcd 不为 1 的最大区间。
通过二分求即可。
Code
ST 表+欧拉序求LCA:
欧拉序,简而言之就是树的深搜,回溯的结点也需要标记。

拿最开始的图来说,他的欧拉序就是:1,3,5,3,6,3,1,4,1。
对于我们要找的两个点的LCA,就是他们两个点(如果一个点出现多次,任取一个)之间的深度最小值。
由于每个节点的深度是静态的,所以我们可以使用 ST 表维护。注意,维护的是区间内最小值的点的编号。
不会的同学可以左转:ST表学习笔记
Code
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现