ST 表学习笔记
目录
-
什么是 ST 表
-
建造 ST 表
-
ST 表查询操作
-
ST 表的适用范围与数据结构的对比
-
模板题
-
结语&参考文献
什么是 ST 表
ST 表,即 Sprase Table,也叫稀疏表。
它主要用于解决 RMQ(Range Minimum/Maximum Query,区间最值查询)问题。
更生动地讲,ST 表就是在
ST 表本质上是动态规划。
建造 ST 表
与线段树、树状数组一样,ST 表要先建造。
假设我们需要求区间最小值。
设
例如,
int dp[数组大小 N][log(N)+5];
如 int minn[100005][20]
。
首先初始化,令
for (int i = 1; i <= n; i++) minn[i][0] = read();
* 程序中为了区分是求最大值还是最小值,将 dp 改成了 minn。不过终究是个名字罢了,不用在意。
状态转移方程很简单:
原因更简单,长度为
外层 for
循环:先枚举长度
内层 for
循环:枚举起点,即
代码:
void build()
{
for (int i = 1; i <= n; i++) minn[i][0] = read();
int k = log2(n);
for (int j = 1; j <= k; j++)
{
int R = n - (1 << j) + 1;
for (int i = 1; i <= R; i++) minn[i][j] = min(minn[i][j-1], minn[i + (1 << (j-1))][j-1]);
}
}
* 代码中的 log2()
是 cmath
库中的函数。
ST 表查询操作
前面已经提到,给定
设
这张图很清晰地讲解了 ST 表的查询操作。
那么代码实现就非常容易了。
int query(int L, int R)
{
int k = log2(R-L+1);
return min(minn[L][k], minn[R - (1<<k) + 1][k]);
}
ST 表的适用范围与数据结构的对比
在这章开始之前,先扔个完整 ST 表代码:
//结构体外的定义
#define N 100005
int n;
//结构体
struct ST
{
int minn[N][20];
void build()
{
for (int i = 1; i <= n; i++) minn[i][0] = read();
int k = log2(n);
for (int j = 1; j <= k; j++)
{
int R = n - (1 << j) + 1;
for (int i = 1; i <= R; i++) minn[i][j] = min(minn[i][j-1], minn[i + (1 << (j-1))][j-1]);
}
}
int query(int L, int R)
{
int k = log2(R-L+1);
return min(minn[L][k], minn[R - (1<<k) + 1][k]);
}
};
ST a;
用结构体封装了,代码很清新吧!
大家观察一下代码,不难发现:
-
build()
的时间复杂度是 。 -
query()
的时间复杂度是 。
我们发现,线段树同样可以解决这类问题。
将线段树拉过来对比一下:
* 前台图炸了,只能在后台截图QwQ
通过表格可以看到,两者各有利弊。
模板题
T1:P1816
求最小。
直接用上文的代码即可。
T2:P3865
求最大。
代码稍微更改一下就好。
T3:P2880
同时维护最大与最小的 ST 表。
查询时作差即可,非常简单。
代码略。
* 如果你真的想学习 ST 表,以上模板题建议从零开始盲打一遍。
结语 & 参考文献
感谢大家看完整篇文章。
大部分内容参考了书籍《算法训练营:进阶篇》。
图片均为自己手绘,图片与文章未经允许不得转载。
首发:2022-05-07 16:35:56
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具