ST表
知识点
st表用于解决可重复贡献问题的数据结构
可重复贡献问题:或,异或,与,gcd,lcm
其本质为动态规划
f[i][j]:从下标i开始,长度为2j的最大值 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]=max(f[i][j−1],f[i+2j−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=log2(r−l+1) k=log2(r-l+1) k=log2(r−l+1)
ans=max(f[l][k],f[r−2k+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;
}
1433

被折叠的 条评论
为什么被折叠?



