LCA转化RMQ(内附RMQ算法ST)

来源:互联网 发布:2017最近的网络流行语 编辑:程序博客网 时间:2024/05/16 11:18

RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题。
如果对一颗树进行dfs遍历 按照遍历的顺序将结点深度和标号写入一个数组d
并记录每个结点被第一次被访问时在d中的位置
如图  则d中的深度如下
1234343232343212
对应的标号如下
1247484252696213  
对于结点7 和9  他们的lca就是 深度区间里最小的那个 也就是2 对应着点2

现在来看RMQ的解决方法:


RMQ问题:区间最小值问题(也可以解决区间最大值问题)


解决算法:ST (Sparse - Table算法,基于动态规划求区间最值的算法) 



ST算法分为预处理和查询两部分 

首先定义数组:我们用定义 Amax[i][j] 为从 i开始的,长度为2^j的区间里面的最大值, Amin[i][j]为从i开始,长度为2^j的区间里面的最小值 





一:预处理如下


我们可以将一段长度为2^j的区间分成两段长度都为2^(j-1)的相同区间 
 
区间1 为  i.....i+2^(j-1)-1   区间2为  i+2^(j-1).....i+2^j-1 
 
得到状态转移方程(由长度递增推出)


Amax[i][j] = max(Amax[i][j-1], Amax[i+2^(j-1)][j-1])
Amin[i][j] = max(Amin[i][j-1], Amin[i+2^(j-1)][j-1])边界条件为F[i][0]=A[i]. 
  
二:查询如下


MAX L R 表示要查询[L, R]区间的最大值
MIN L R 表示要查询[L, R]区间的最小值


我们需要找到这样一个k值,使得从L开头的一个长度为2^k的区间 和 以R结尾的长度为2^k的区间 包括了整个[L, R]


k值计算有两种方案  1,k =(int) log2( R-L+1)  2,k值从0开始递增 直到2^k大于 R-L+1 为止。
 
找到k后,查询操作有


return max(Amax[L][k], Amax[R-(1<<k)+1][k]);//返回区间最大值


return min(Amin[L][k], Amin[R-(1<<k)+1][k]);//返回区间最小值

原创粉丝点击