RMQ问题总结,标准RMQ算法的实现
RMQ问题:对于长度为N的序列,询问区间[L,R]中的最值
RMQ问题的几种解法:
- 普通遍历查询,O(1)-O(N)
- 线段树,O(N)-O(logN)
- DP,O(NlogN)-O(1)
- RMQ标准算法,O(N)-O(1)
简单介绍:
- 朴素的查询,不需要任何预处理,但结果是没有任何已知的信息可以利用,每次都需要从头遍历到尾。
- 线段树,区间问题的神器,用线段树做比起朴素的暴力查询要快得多,关键在于线段树使用了分治思想,利用了区间问题的可合并性。任何一个区间最多只需要logN个线段树上的区间来合并,线段树上的区间总数目为O(N)个,因此只需要O(N)的预处理就可以将查询复杂度降到O(logN)。同时线段树的树状结构使得修改时信息更容易维护。
- DP,又叫ST算法,也是利用了分治的思想。任何一个区间都可以由两个小于当前区间长度的最大的长度为2的幂的区间合并而来,于是预处理出每个点开始所有长度为2的幂的区间最值,那么查询时就可以由预处理的信息O(1)得到答案。
- RMQ标准算法,利用了神奇的数据结构--笛卡尔树,笛卡尔树将区间最值问题转化为树上两个点的LCA问题,而DFS可以将LCA问题转化为±1RMQ问题,±1RMQ问题又可以利用分块和动态规划的思想来解决。上述所有预处理,包括笛卡尔树的建立、DFS序以及±1RMQ的问题的求解都可以在线性时间内完成,查询时复杂度为O(1)。
标准算法的实现:
- 结构图:

- 笛卡尔树的构造算方法:从左至右扫描原序列,并依次插入到笛卡尔树的右链中,使用单调栈复杂度为O(N)。建好树后,key是二查搜索树,value是小根堆。
- 最小值与LCA:建好树后,区间最小值问题便转化为了LCA问题,下面简单证明一下:

假设现在询问[d, f]的最小值,root为d和f的LCA,由笛卡尔树的性质可知,root是整棵树表示区间的最小值,而[d, f]是其子区间,所以root不可能比[d, f]中的数小,又因为d和f属于root的不同子树(LCA的性质),所以root一定在[d, f]中(笛卡尔树的性质),故对两个点a,b,LCA(a, b)就是[a, b]的最小值,证毕。
- ±1RMQ问题:相邻两个数相差1或者-1的序列的RMQ问题
- ±1RMQ问题解法:将原长度为N的序列分成2N/logN块,每块长度为logN/2,将原来的询问分解为块间询问和块内询问。用ST算法在O(N/logN*log(N/logN))=O(N)的时间内处理出块与块之间的区间最值信息,可以在O(1)的时间内解决块与块之间的询问。对于块内的询问,由于每块长度为logN/2,相邻两个数的差不是1就是-1,于是对于区间最值出现的位置,本质不同的状态只有2logN/2=√N个,加上边界,总共状态数为O(√N*logNlogN),利用递推在O(√N*logNlogN)的时间内求出所有状态来,以后可以在O(1)的时间内得到块内任意区间最值的位置。总复杂度为O(N + √N*logNlogN) ≈ O(N)。
- LCA与±1RMQ的经典转化就不细说了,详见代码
标准RMQ,O(N)-O(1)
1 |
struct PlusMinusOneRMQ {
|
RMQ问题总结,标准RMQ算法的实现的更多相关文章
- Bug2算法的实现(RobotBASIC环境中仿真)
移动机器人智能的一个重要标志就是自主导航,而实现机器人自主导航有个基本要求--避障.之前简单介绍过Bug避障算法,但仅仅了解大致理论而不亲自动手实现一遍很难有深刻的印象,只能说似懂非懂.我不是天才,不 ...
- Canny边缘检测算法的实现
图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波.我们知道微分运算是求信号的变化率,具有加强高频分量的作用.在空域运算中来说,对图像的锐化就是计算微分.由于数字图像的离散信号, ...
- C++基础代码--20余种数据结构和算法的实现
C++基础代码--20余种数据结构和算法的实现 过年了,闲来无事,翻阅起以前写的代码,无意间找到了大学时写的一套C++工具集,主要是关于数据结构和算法.以及语言层面的工具类.过去好几年了,现在几乎已经 ...
- java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现
java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析 ...
- SSE图像算法优化系列十三:超高速BoxBlur算法的实现和优化(Opencv的速度的五倍)
在SSE图像算法优化系列五:超高速指数模糊算法的实现和优化(10000*10000在100ms左右实现) 一文中,我曾经说过优化后的ExpBlur比BoxBlur还要快,那个时候我比较的BoxBlur ...
- 详解Linux内核红黑树算法的实现
转自:https://blog.csdn.net/npy_lp/article/details/7420689 内核源码:linux-2.6.38.8.tar.bz2 关于二叉查找树的概念请参考博文& ...
- 详细MATLAB 中BP神经网络算法的实现
MATLAB 中BP神经网络算法的实现 BP神经网络算法提供了一种普遍并且实用的方法从样例中学习值为实数.离散值或者向量的函数,这里就简单介绍一下如何用MATLAB编程实现该算法. 具体步骤 这里 ...
- Python学习(三) 八大排序算法的实现(下)
本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过 ...
- Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。
Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得 ...
随机推荐
- 运行一个nodejs服务,先发布为deployment,然后创建service,让集群外可以访问
问题来源 海口-老男人 17:42:43 就是我要运行一个nodejs服务,先发布为deployment,然后创建service,让集群外可以访问 旧报纸 17:43:35 也就是 你的需求为 一个a ...
- [php] 简单的实现一个错误接管类
自己弄的一个错误接管类: <?php //---------------------------------- // Leephp 错误接管类 // 2017-07-06 // Pengchon ...
- redis: 其他数据类型(八)
1.geospatial 地理位置 有效的经度从-180度到180度 有效的纬度从-85.05112878度到85.05112878度 当坐标位置超出上述指定范围时,该命令将会返回一个错误 底层实现原 ...
- 美的PDF转换成Word转换器完全免费
下载地址:百度网盘提取码:02ap 安装破解步骤:先安装主程序,末尾是full结尾的,安装完成后不要打开软件,然后接着安装破解补丁,即可破解成功! 需要的老铁们直接拿去用吧,亲测好用!有配套的功能强大 ...
- 取代 Python 多进程!伯克利开源分布式框架 Ray
Ray 由伯克利开源,是一个用于并行计算和分布式 Python 开发的开源项目.本文将介绍如何使用 Ray 轻松构建可从笔记本电脑扩展到大型集群的应用程序. 并行和分布式计算是现代应用程序的主要内容. ...
- TensorFlow keras 迁移学习
数据的读取 import tensorflow as tf from tensorflow.python import keras from tensorflow.python.keras.prepr ...
- 用scanf、printf输入输出string型字符串
c语言里是没有string型的,string在c++里面.有的时候在c++里要用scanf.printf输入输出string型字符串,这是可以实现的,不过要做一点处理. 具体操作看代码: #inclu ...
- 第九次-DFA最小化,语法分析初步
1.将DFA最小化:教材P65 第9题 2.构造以下文法相应的最小的DFA S→ 0A|1B A→ 1S|1 B→0S|0 3.自上而下语法分析,回溯产生的原因是什么? 4.P100 练习4,反复提取 ...
- 2019-2020-1 20199303《Linux内核原理与分析》第六周作业
系统调用的三层机制 首先是为系统增加新的命令 运行脚本自动生成文件系统 其中有一个显示时间的功能 编辑test.c文件,增加一个hello函数用来显示学号,再次使用make roofts自动编译,调用 ...
- Android自绘制控件
开发过程中,我们免不了需要用到一些自定义的 View,自定义 View 一般可分为三类: ① 继承类 View —— 一般继承系统以后的基本 View,新增/重置一些自定义属性 ,例如两端对齐的Tex ...