ST表标程
P3865 ST表板子题
ST表是通过倍增算法快速处理RMQ问题的一个算法
#include <bits/stdc++.h>
using namespace std;
const int logn=21;
const int maxn=2000001;
int f[maxn][logn+1],Logn[maxn+1];//f是[i,2^j-1]的最大值,Logn看函数
inline int FRead(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;}
void pre(){//提前算好log2(n)
Logn[1]=0;
Logn[2]=1;
for(int i=3;i<maxn;i++){
Logn[i]=Logn[i/2]+1;
}
}
int main(){
int n=FRead(),m=FRead();
for(int i=1;i<=n;i++)
f[i][0]=FRead();
pre();
for(int j=1;j<=logn;j++)//j在外面,因为递推需要
for(int i=1;i+(1<<j)-1<=n;i++)//注意i的范围,不然对应j会超出n
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); //实现ST表
for(int i=1;i<= m;i++) {
int x=FRead(),y=FRead();//每次询问
int l=Logn[y-x+1];//长度
printf("%d\n",max(f[x][l],f[y-(1<<l)+1][l]));//通过分成两个区间,取得区间内最大值
}
return 0;
}
区间gcd和RMQ是本质上一样的问题,
只需要把主函数作出如下修改:
int main(){
int n=FRead(),m=FRead();
for(int i=1;i<=n;i++)
f[i][0]=FRead();
pre();
for(int j=1;j<=logn;j++)//j在外面,因为递推需要
for(int i=1;i+(1<<j)-1<=n;i++)//注意i的范围,不然对应j会超出n
f[i][j]=__gcd(f[i][j-1],f[i+(1<<(j-1))][j-1]); //实现ST表
for(int i=1;i<= m;i++) {
int x=FRead(),y=FRead();//每次询问
int l=Logn[y-x+1];//长度
printf("%d\n",__gcd(f[x][l],f[y-(1<<l)+1][l]));//通过分成两个区间,取得区间内最大值
}
return 0;
}

浙公网安备 33010602011771号