RMQ问题的几种解决方案
来源:互联网 发布:淘宝女装排名 编辑:程序博客网 时间:2024/05/21 15:38
RMQ作为学习Suffix Array的基本知识之一,我想在写SA总结之前写下这一部分的知识。
RMQ问题可以算是经典问题中的经典,目的就是希望用较短的时间完成求区间最小值的操作。
方法有很多种,最简单的直接线性统计的效率极其低下,也比较白痴,差不多都应该会。
下面讲下几个比较好的RMQ问题的算法。
方法一:线段树
线段树作为维护区间性质的最佳利器,绝对是不错的选择。写起来可以递归,非常的方便。
但是他也是有缺点的,最大的问题就是虽然说是O(nlogn)-O(logn)的时间复杂度中的常数比较大。从实际运行效率上看不是很好。
我前面的日志里面写过一些线段树的题,线段树的用法大同小异,也比较好学,这里不再赘述。
方法二:RMQ的ST算法
ST算法是一个很不错的算法,复杂度为O(nlogn)-O(1)。这种算法运用的主要思想是倍增思想。
倍增思想的核心就是,通过递推使得结论成倍地提高。
这里我们定义这样一个数组f[i,j]表示从i开始向后数2j个元素的RMQ
递推方程就是
f[i,j]:=min(f[i,j-1],f[i+1 shl (j-1),j-1]);
边界:f[i,0]:=a[i];
这样我们就可以用这样的式子来解决RMQ问题:
设k:=trunc(ln(j-i+1)/ln(2))
RMQ(i,j):=min(f[i,k],f[j-(1 shl k)+1,k]);
对于某一些特殊的RMQ问题还有O(n)-O(1)的算法,方法在于分成长度特殊的段,然后再用这些段RMQ。这是将LCA问题转化为RMQ问题的途径。
方法三:笛卡尔树
这个方法的精髓在于将RMQ问题转化为LCA问题。
笛卡尔树的定义是,对于一个数组A来说,笛卡尔树的根的编号是这个数组的最小值的所在的编号k。他的左子树就是在数组A[1..k-1]上的一棵笛卡尔树,右子树是一棵在数组A[k+1..n]的一棵笛卡尔树。
这样RMQ(A,i,j)就被转化成了LCA(T,i,j)。
因为LCA问题离线Tarjan算法的复杂度是O(n)的,所以这个问题最终的复杂度在O(n)。
我的理解就是理论性比较强,并没有什么实际意义。
缺点是不支持在线提问。
以上就是RMQ问题的几种经典方法,如果想要透彻的理解好线段树和倍增法,还是需要一些题目的磨练。
推荐的一个题是MIPT上的105号MRQ Problem。数据真的是很强,有很多地方要注意,用ST时候要格外注意内存。
另外用P的同学,请使用Kylix编译器提交,否则这辈子估计过不了了啊……
线段树的代码以前贴过,这里给下我的ST算法的代码:
- RMQ问题的几种解决方案
- RMQ问题的4解决方案
- Java Web中文问题的几种解决方案
- iBatis n+1选择问题 的几种解决方案
- 关于Win7下QTP的几种问题和解决方案
- Android内存问题的几种解决方案(一)
- Android内存问题的几种解决方案(二)
- 前端跨域问题的几种解决方案
- 常见的几种浏览器问题以及解决方案
- RMQ问题的三种解法
- RMQ的问题
- RMQ问题的ST算法
- RMQ问题的ST算法
- LCA问题的RMQ做法
- RMQ问题的ST算法
- zepto的tap事件的点透问题的几种解决方案
- 图片上传的跨域问题的几种解决方案和细节及优缺点
- 图片上传的跨域问题的几种解决方案和细节及优缺点
- oracle
- 夜曲
- TULING第二十天
- 传智播客--进销存之自定义注解,数据字典和通用配置
- matlab优化应用
- RMQ问题的几种解决方案
- (表格)vba如何打开一个文件夹下所有xls文件
- Android模拟器使用参数详解
- c++问题
- C++内联函数与宏定义
- oracle 9i 在安装到Oracle Database Configuration assistant 的时候装不下去了,等了2个小时没有反应 失败
- 浏览器工作原理
- 网页发布到互联网尝试
- QTP测试.NET控件CheckedListBox