RMQ算法

来源:互联网 发布:网络聊天英语 编辑:程序博客网 时间:2024/05/10 20:28

Range Maximum(Minimum) Query的缩写,顾名思义是用来求某个区间内的最大值或最小值,通常用在需要多次询问一些区间的最值的问题中。

 

描述:输入N个数和M次询问,每次询问一个区间[L,R],求第L个数到R个数之间的最大值或者最小值。

 

原理:用A[1..N]表示一组数,F[I,J]表示从A[I]到A[I+2^J-1]这个范围内的最大值,也就是以A[I]为起点连续2^J个数的最大值,由于元素个数为2^J个,所以从中间平均分成两部分,每一部分的元素个数刚好为2^(J-1)个,如下图:

 
 
整个区间的最大值一定是左右两部分最大值的较大值,满足动态规划的最优原理
状态转移方程:
F[I,J]=max(F[I,J-1],F[I+2^(J-1),J-1])
边界条件为F[I,0]=A[I]
这样就可以在O(NlgN)的时间复杂度内预处理F数组
 
预处理F数组
 
for(int i=1;i<=n;i++)
   f[i,0]:=a[i];
for(int j=1;j<=ln(n)/ln(2);j++)
{
   for(int i=1;i<=n+1-1<<j;i++)
     f[i,j]=max(f[i,j-1],f[i+1<<(j-1),j-1]); 
};
 
 
对于询问[L,R],求其区间最大值,则可以先求出一个最大的x,x满足2^x<=R-L+1(很明显,2^(x+1)>=R-L+1),即x=ln(R-L+1)/ln(2),所以,下面用的到个区间一定能包含整个[L,R]区间。
[L,R]=[L,L+2^x-1] ∪[R+1-2^x,R],两个子区间元素个数都是2^x个,如图
 
ANS(L,R)=max(F[L,x],F[R+1-2^x,x])
对于L,r中间的最大值
long query(long l,long r)
{
  long x=ln(r-l+1)/ln(2);
  return (max(f[l,x],f[r+1-1<<x,x]));
}
 
 


 
原创粉丝点击