rmq
Posted noncontradiction
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rmq相关的知识,希望对你有一定的参考价值。
rmq是求区间的最大或者最小值的,但不可以修改值,时间复杂度nlgn,空间复杂度nlgn
开辟了n*lgn的二维数组,也就是ma[n][lgn],mi[n][lgn]分别代表最大和最小
对于ma[i][j]代表,a[i]~a[i+(1<<j)-1]中最大的值 1<<j其实就是2的j次幂
所以初始化数组,ma[i][j]=max(ma[i][j-1],ma[i+(1<<(j-1))][j-1]),其实就是把2^j的区间分成两半,这两块最大值中较大的就是整个区间最大值,mi数组同理
void init()
{
for(int i=1;i<=n;i++)
ma[i][0]=a[i];
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i+(1<<j)-1<=n;i++)
{
ma[i][j]=max(ma[i][j-1],ma[i+(1<<(j-1))][j-1]);
}
}
}
对于查询一个区间l~r的最大值,因为任何一个区间长度len一定是存在 2^k<=len<2*2^k,那么我们如果找到k, ma[l][k]和ma[r-(1<<k)+1][k]一定覆盖整个区间
int rmqma(int l,int r)
{
int k=log2(r-l+1);
return max(ma[l][k],ma[r-(1<<k)+1][k]);
}
以上是关于rmq的主要内容,如果未能解决你的问题,请参考以下文章