ST表
知识点
st表用于解决可重复贡献问题的数据结构
可重复贡献问题:或,异或,与,gcd,lcm
其本质为动态规划
f
[
i
]
[
j
]
:
从下标
i
开始,长度为
2
j
的最大值
f[i][j]:从下标i开始,长度为2^j 的最大值
f[i][j]:从下标i开始,长度为2j的最大值
初始化:
f
[
i
]
[
0
]
=
a
[
i
]
f[i][0]=a[i]
f[i][0]=a[i]
状态转移方程:
f
[
i
]
[
j
]
=
m
a
x
(
f
[
i
]
[
j
−
1
]
,
f
[
i
+
2
j
−
1
]
[
j
−
1
]
)
f[i][j]=max(f[i][j-1],f[i+2^j-1 ][j-1])
f[i][j]=max(f[i][j−1],f[i+2j−1][j−1])
将一个区间分割成两个:
k次方:
k
=
l
o
g
2
(
r
−
l
+
1
)
k=log2(r-l+1)
k=log2(r−l+1)
a n s = m a x ( f [ l ] [ k ] , f [ r − 2 k + 1 ] [ k ] ) ans=max(f[l][k],f[r-2^{k+1}][k]) ans=max(f[l][k],f[r−2k+1][k])
示例代码
#include<bits/stdc++.h>
using namespace std;
int f1[50005][40],f2[50005][40],a[50005];
int n,q;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
f1[i][0]=a[i];
f2[i][0]=a[i];
}
int x=log2(n);
for(int j=1;j<=x;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
f1[i][j]=max(f1[i][j-1],f1[i+(1<<(j-1))][j-1]);
f2[i][j]=min(f2[i][j-1],f2[i+(1<<(j-1))][j-1]);
}
}
while(q--){
int r,l;
cin>>l>>r;
int k=log2(r-l+1);
cout<<max(f1[l][k],f1[r-(1<<k)+1][k])<<endl;
cout<<min(f2[l][k],f2[r-(1<<k)+1][k])<<endl;
}
return 0;
}