ST表
440 字
2 分钟
ST表
ST 表适用于解决可重复贡献问题.
可重复贡献问题
在统计时,一个元素被统计多次对结果没有影响(即对于任意的运算 ,存在 ),常见的可重复贡献问题有:求区间最值(RMQ)、区间按位与、区间按位或、区间 gcd等.
ST 表使用倍增的思想.我们现在想要快速求序列 中的区间最小值,需要维护以下数据:
f[j][i]:从i开始,长度为 的序列的最小值.
f 数组可以通过递推的方式预处理出来,每次计算 的最小值时,可以拆分为 和 这两个区间中的较小值,递推关系如下:
显然,初始条件为:.预处理时间复杂度 .
for (int i = 0; i <= n; i++) { st[0][i] = a[i];}for (int j = 1; j <= 17; j++) { for (int i = 1; i + (1 << j) - 1 <= n; i++) { st[j][i] = min(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]); }}在查询 的最小值时,我们可以将长度 取 .设结果为 ,则 必定大于等于 的一半,且小于 .此时,答案为从 开始,长度为 的区间,和末尾为 ,长度为 的区间的最小值.这两个区间的交集必然是 .可以列出表达式:
查询复杂度是 的.
int query(int l, int r) { int len = log2(r - l + 1); return min(st[len][l], st[len][r - (1 << len) + 1]);}<< 的优先级问题在 C++ 中, << 和 >> 的优先级是低于 + 和 - 的,因此在进行左移和右移运算时,一定要注意括号问题.
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!


