ST表模板(求区间最值问题)
ST表的介绍
st表是一种\(O(nlogn)\)预处理,\(O(1)\)查询的数据结构,常用来处理静态数组的区间最值,区间gcd等问题。
st表用到的核心思想是倍增。
ST表的原理
定义st[i][j]表示从下标 \(i\) 开始到下标 \(i+2^j\) 这段区间的答案。\((i \leqslant n,\quad 2^j \leqslant n)\)
预处理代码:
for(int i = 1;i <= n; i++) Max[i][0] = a[i];
lg2[1] = 0;
for (int i = 2; i <= n; ++i) lg2[i] = lg2[i >> 1] + 1; //预处理之后会用到的log2函数
for(int j = 1;j <= bi; j++)
for(int i = 1; i + (1 << j) - 1 <= N; i++)
Max[i][j] = max(Max[i][j - 1], Max[i + (1 << (j - 1))][j - 1]);
查询:
区间长度\(len\)。
首先计算得到一个\(2^k\),保证 \(\frac{len}{2} \leqslant 2^k \leqslant len\)。
查询时候分别通过 \(l到l + 2^j\)以及 \(r到r-2^j\)来覆盖整个查询区间。
因为\(max,min,gcd\)等的性质: 单点的重复计算没有贡献
int stQuery(int l,int r){
int k = lg2[r - l + 1];
return max(Max[l][k], Max[r - (1 << k) + 1][k]);
}
本人的ST表模板:
struct ST{
int N, bi; //根据需要传入数组大小和2的幂次
vector<vector<int>> Max;
vector<int> lg2;
ST(int n = 1e5 + 1, int bi = 21): N(n), bi(bi) {
Max.resize(n + 1, vector<int>(bi + 1, 0));
lg2.resize(n + 1, 0);
}
void stBuild(int n, int a[]){
for(int i = 1;i <= n; i++) Max[i][0] = a[i];
lg2[1] = 0;
for (int i = 2; i <= n; ++i) lg2[i] = lg2[i >> 1] + 1;
for(int j = 1;j <= bi; j++)
for(int i = 1; i + (1 << j) - 1 <= N; i++)
Max[i][j] = max(Max[i][j-1], Max[i + (1 << (j - 1))][j - 1]);
}
int stQuery(int l,int r){
int k=lg2[r - l + 1];
return max(Max[l][k],Max[r-(1<<k)+1][k]);
}
};
洛谷模板题:
P3865 【模板】ST 表
int a[N];
struct ST{
int N, bi;
vector<vector<int>> Max;
vector<int> lg2;
ST(int n = 1, int bi = 1) : N(n), bi(bi) {
Max.resize(n + 1, vector<int>(bi + 1, 0));
lg2.resize(n + 1, 0);
}
void stBuild(int n, int a[]){
for(int i = 1;i <= n; i++) Max[i][0] = a[i];
lg2[1] = 0;
for (int i = 2; i <= n; ++i) lg2[i] = lg2[i >> 1] + 1;
for(int j = 1;j <= bi; j++)
for(int i = 1; i + (1 << j) - 1 <= N; i++)
Max[i][j] = max(Max[i][j-1], Max[i + (1 << (j - 1))][j - 1]);
}
int stQuery(int l,int r){
int k=lg2[r - l + 1];
return max(Max[l][k],Max[r-(1<<k)+1][k]);
}
};
void solve(int ce){
int q;
cin >> n >> q;
for(int i = 1; i <= n; i++)cin >> a[i];
ST st(n,21);
st.stBuild(n, a);
while(q--){
int l, r;
cin >> l >> r;
cout << st.stQuery(l, r) << endl;
}
}

浙公网安备 33010602011771号