题意:多次询问[l,r]之间的最大值
思路:倍增思想,f[i][j]表示从i开始 长度为2^j的区间 的最大值
① 预处理
② 查询
假设目标区间长度为len,找到k 满足
&&
,即
最大值即为
int f[N][M];
//f[i][j] 从i开始 长度为2^j的区间 的最大值
//f[i][j]=max(f[i][j-1],f[i+2^(j-1)][j-1])
//假设目标区间长度为len
//找到k 满足 2^k<=len && 2^(k+1)>len
//即k=log(len)/log(2)
void init(){
for(int j=0;j<M;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
if(!j) f[i][j]=w[i];
else{
f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);
}
}
}
}
int query(int l,int r){
int len=r-l+1;
int k=log(len)/log(2);
return max(f[l][k],f[r-(1<<k)+1][k]);
}