题解这块/.
2025-08-02 14:26:42
发布于:上海
29阅读
0回复
0点赞
#include<iostream>
using namespace std;
const int N=5e5+5;
int a[N];//第二维j=log(N)
int f[N][22];//空间复杂度O(nlogn)
int logn[N+1];
void init(){
logn[1]=0;//2^0=1
logn[2]=1;//2^1=2
for(int i=3;i<N;i++)
logn[i]=logn[i/2]+1;
//logA+logB=logA+B
//log(i/2)+log2=log(i/2*2)=logi
}
int main(){
int m,n;
cin>>m>>n;
for(int i=1;i<=m;i++){
cin>>a[i];
f[i][0]=a[i];//初始化
}
init();//预处理时间复杂度O(nlogn)
for(int j=1;j<=21;j++)
for(int i=1;i+(1<<j)-1<=m;i++)
//左半区间 [i,i+2^{j-1}-1]
//右半区间 [i+2^{j-1},i+s^{j}-1]
f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
//查询时间复杂度O(1)
while(n--){
int l,r;
cin>>l>>r;
//查询区间长度len=r-l+1
int s=logn[r-l+1];//区间长度的最大幂
cout<<min(f[l][s],f[r-(1<<s)+1][s])<<" ";
}
return 0;
}
/*min[l][r] 求区间最小 for(l-r)
RMQ-ST表
f[i][j] 从位置i开始,长度为2^j的区间最小值
f[i][j]=min{a[i],a[i+1]...a[i+2^j-1]}
状态转移方程:f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1])
f[i][0] 从i开始区间长度为1 可代表a[i]
f[i][0]=a[i] 初始条件
f[i][1] 从i开始区间长度为2
*/
这里空空如也
有帮助,赞一个