ST表(Sparse Table)是一种用于解决范围最值查询问题的数据结构。它可以以较小的空间复杂度提供快速的查询效率。以下是一个C++模板,展示了如何实现ST表。
#include <iostream>
#include <vector>
#include <cmath>
// ST表的实现
template<typename T>
class SparseTable {
private:
std::vector<std::vector<T>> st; // ST表
std::vector<int> log2; // 预计算log值
public:
// 构造函数,接收一个数组作为输入,建立ST表
SparseTable(const std::vector<T>& arr) {
int n = arr.size();
log2.resize(n + 1, 0);
for (int i = 2; i <= n; i++) {
log2[i] = log2[i / 2] + 1;
}
st.assign(n, std::vector<T>(log2[n] + 1));
for (int i = 0; i < n; i++) {
st[i] = arr[i];
}
for (int j = 1; (1 << j) <= n; j++) {
for (int i = 0; i + (1 << j) - 1 < n; i++) {
st[i][j] = std::min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
}
}
// 查询区间[l, r]的最小值
T query(int l, int r) {
int j = log2[r - l + 1];
return std::min(st[l][j], st[r - (1 << j) + 1][j]);
}
};
int main() {
// 示例用法
std::vector<int> arr = {1, 3, 4, 8, 6, 1, 4, 2};
SparseTable<int> st(arr);
std::cout << "Minimum in range [1, 3]: " << st.query(1, 3) << std::endl;
std::cout << "Minimum in range [0, 7]: " << st.query(0, 7) << std::endl;
std::cout << "Minimum in range [4, 7]: " << st.query(4, 7) << std::endl;
return 0;
}
在这个模板中,我们首先预计算了每个位置i
对应的值,以便于后续快速计算区间长度对应的
j
值。然后,我们建立了一个二维数组st
,其中表示从位置
i
开始,长度为的区间的最小值。
在构造函数中,我们初始化了st
的第一列,然后通过动态规划的方式填充其他列,确保每个区间的最小值都可以快速计算得到。
查询时,我们首先计算出查询区间长度对应的值,然后返回两个覆盖整个查询区间的区间的最小值。
这个模板假设查询的是最小值,如果需要查询最大值或其他 操作,只需要在构造函数和查询函数中相应地修改操作即可。