『数据结构』RMQ问题

RMQ(Range Minimum/Maximum Query),即区间最值问题。

对于长度为 n 的数列 A ,回答若干查询 RMQ(A,i,j)(i,j<=n) ,返回数列 A 中下标在 i,j 里的最大(小)值。

相关算法

  1. 朴素(搜索),时间复杂度:\(O(n)-O(q \times n)\) ,在线;
  2. 线段树,时间复杂度:$O(n)-O(q\times logn) $,在线;
  3. ST(动态规划),时间复杂度:\(O(n\times logn)-O(q)\),在线;
  4. RMQ标准算法,先规约为LCA,再规约成约束RMQ ,时间复杂度:\(O(n)-O(q)\),在线。

ST 算法

假设当前题目要求区间最小值,我们令 dp[i][j] 代表从 i 开始,长度为\(2^{j}\)这段区间的最小值。

于是便有:\(dp[i][j]=min(dp[i][j-1],dp[i+^{j-1}][j-1])\)

分析可知,\(dp[i][j-1]\)代表从 i 开始,长度为\(2^{j}\)区间一半中的最小值,而 \(dp[i+2^{j-1}][j-1]\)即为区间的另一半。

即为区间的另一半。

最终(从下往上看):

\(dp[0][*]\) \(dp[1][*]\) \(dp[2][*]\) \(dp[3][*]\) \(dp[4][*]\) \(dp[5][*]\) \(dp[6][*]\) \(dp[7][*]\)
\(dp[*\)][3] \(1\)
\(dp[*\)][2] \(1\) \(1\) \(1\) \(5\) \(2\)
\(dp[*][1]\) \(3\) \(1\) \(1\) \(5\) \(7\) \(6\) \(2\)
\(dp[*][0]\) \(4\) \(3\) \(1\) \(5\) \(7\) \(8\) \(6\) \(2\)

预处理

根据状态转移方程,首先指定当区间长度为\(2^{0}\)时的各初始值,随后推出后面的结果。

void ST_Init(const vector<int> &A) {
    int n=A.size();
    for (int i=0; i<n; i++)
        dp[i][0]=A[i];
    for (int j=1; (1<<j)<=n; j++)
        for (int i=0; i+(1<<j)<=n; i++)
            dp[i][j]=min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
}

查询

预处理出整个 dp 数组以后,查询操作很简单,令 k 为满足\(2^{k} \leq R-L+1\)的最大整数,则以 L 开头、以 R 结尾的两个长度为\(2^{k}\)的区间合起来即覆盖了查询区间 [L,R]

int RMQ(int L, int R) {
    int k=0;
    while ((1<<(k+1))<=R-L+1) k++;
    return min(dp[L][k], dp[R-(1<<k)+1][k]);
}

嗯!怎么说呢?感觉线段树在这种类型的题目中好像是最万能的方法了。

无论是 [点修改+查询] 还是 [区间修改+查询] ,它都可以做到 \(O(logn)\)的复杂度,而且在线段树中我们也可以维护好多东西(区间和、最值等等)。

对于一维中的线段树,我们想要查询某个区间的最值,首先就应该建树咯~(具体方法省略

而在查询时,我们可以从根节点向下递归搜索,如下图,假设查询区间为 [2,6]

[2,6] 这一个大区间分解为不相交的三个小区间 [2,3]、[4,5]、[6] ,而最终的结果便由这三个节点中所维护的信息决定的!

我们假设查询还是区间最小值,于是最终的结果为\(\min(1,7,6)=1\)

线段树可以解决普通的 [点/区间] 修改+查询 ,当然它也可以解决 树中的路径权值 修改+查询(树链剖分)。

原文地址:https://www.cnblogs.com/shenxiaohuang/p/10162100.html

时间: 2024-08-04 07:31:02

『数据结构』RMQ问题的相关文章

『数据结构』树状数组

树状数组的问题模型: 现在有一个这样的问题: 有一个数组\(a\),下标从\(0\)到\(n-1\),现在你要进行\(w\)次修改,\(q\)次查询. 修改是修改数组中某一个元素的值: 查询是查询数组中任意一个区间的和,\(w+q<500000\). 这个问题很普遍,首先分析下朴素做法的时间复杂度, 修改是\(O(1)\)的时间复杂度, 而查询就要\(O(n^2)\)的复杂度,总体时间复杂度为\(O(q*q*n*n)\): 你或许会想到用前缀和来优化这个查询, 我们再来分析下,查询的话是\(O(

『数据结构』线段树

线段树原理 线段树,类似区间树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为\(O(logn)\). 线段树的每个节点表示一个区间,子节点则分别表示父节点的左右半区间,例如父亲的区间是\([a,b]\),那么\((c=(a+b)/2)\)左儿子的区间是\([a,c]\),右儿子的区间是\([c+1,b]\). 下面我们从一个经典的例子来了解线段树,问题描述如下:从数组a[0...n-1]中查找某个数组某

『TensorFlow』以GAN为例的神经网络类范式

1.导入包: import os import time import math from glob import glob from PIL import Image import tensorflow as tf import numpy as np import ops # 层函数封装包 import utils # 其他辅助函数 2.简单的临时辅助函数: def conv_out_size_same(size, stride): # 对浮点数向上取整(大于f的最小整数) return i

『电子书』分享一波码农必备编程开发类书籍[转]

layout: default title: 『电子书』分享一波码农必备编程开发类书籍[转] category: [技术, C/C++] comments: true --- 分享一些书籍 看到书籍很多,感觉很不错,就收藏下来了,是百度盘的连接,失效的可以评论一下以此更新一下连接. 书籍清单 Python编程快速上手 细说PHP(第2版) Python核心编程(第3版) Linux命令行与shell脚本编程大全(第3版) python高手之路 iOS编程(第4版) Python编程:从入门到实践

『ENGLISH』

以A字母开头的词汇 英文 中文 abstract module 抽象模组 access 访问.存取 access control 存取控制 access control information 存取控制资讯 access mechanism 存取机制 access rights 存取权限 accessibility 无障碍性 accessibility information 无障碍网页资讯 accessibility problem 无障碍网页问题 accessible 无障碍的 access

『TensorFlow』函数查询列表_神经网络相关

神经网络(Neural Network) 激活函数(Activation Functions) 操作 描述 tf.nn.relu(features, name=None) 整流函数:max(features, 0) tf.nn.relu6(features, name=None) 以6为阈值的整流函数:min(max(features, 0), 6) tf.nn.elu(features, name=None) elu函数,exp(features) - 1 if < 0,否则featuresE

『数据库』随手写了一个 跨数据库 数据迁移工具

随手写了一个 跨数据库 的 数据迁移工具:>目前支持 SQLServer,MySql,SQLite: >迁移工具 可以自动建表,且 保留 主键,自增列: >迁移工具 基于 Laura.Source  ORM框架 开发: >迁移工具 支持 崩溃恢复(重启迁移工具,将会继续 未完成的 数据迁移): >每张表一个事务(即使  表中有 >100W 的数据,也是一个事务完成): >迁移后 的 自增列 和 原数据库 保持一致: 只是展示一下,直接上图片: 操作工具: 迁移工具

『AngularJS』$location 服务

参考: ng.$location Developer Guide: Angular Services: Using $location 简介 $location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用.改变在地址栏中的URL会作用到$location服务,同样的,改变$location服务也会改变浏览器的地址栏.(可以使用$location进行重定向等操作) $location服务: 暴露浏览器地址栏中的URL,让你可以: 监察URL.

谈谈前端『新』技术

技术这个行当,永远会有新东西出来,不进则退.更关键的是,前端比起整个软件工程乃至计算机科学体系来说,是个相对新生草莽的领域,近年来前端生态的发展其实都是在向其他领域吸收和学习,不论是开发理念.工程实践还是平台本身(规范.浏览器).所谓的『根正苗红』的前端,不过是整个发展进程中探索的一个阶段而已,那个时代的最佳实践,很多到今天都已经不再适用.过往的经验固然有价值,但这些经验如果不结合对新事物本身的了解,就很难产生正确的判断.这里需要强调的是,学习新事物并不是为了不考虑实际需求的滥用,而是为了获取足