\(0.\) RMQ问题

P1816

人话翻译

给定一个长度为\(n\)的数列\(a\),然后有\(m\)组询问,每次询问一个区间\([l,r]\)的最小值。

其中\(m,n\leq10^5\)

\(1.\) 暴力做法

很显然,暴力做法就是便历 \(\max\limits_{l\leq i\leq r}a_i\) 。这个做法最坏时间复杂度将会高达\(O(n^2)\)。很显然,这对于\(1e5\)的数据范围要炸

\(2.\) 正解

线段树

如果不知道什么是线段树,请点击这里 线段树

对于这种区间信息,线段树显然是能够维护的。但鉴于本题没有区间修改,线段树显然有点大材小用,并且数组模拟的线段树空间将会达到\(O(4n)\)

线段树还有一些缺点,就是它的查询时间复杂度最坏是\(O(logn)\)的,因为没有区间修改,这个时间开销也略微有点大。

\(ST\)表(倍增)

倍增算法的含义就是成倍增长。我们考虑一个这样的数据结构:

一个二维数组\(st\),其中

\[st_{i,j}=\min\limits_{i\leq k\leq i+2^j}a_k
\]

我们假设一个数据:\(9\ 3\ 1\ 7\ 5\ 6\ 0\ 8\)

可以建立如下所示的\(ST\)表:

建表

我们发现,我们可以一层层地建表。这样,我们就可以通过递推,利用上层的信息,建表。

我们先将读入数据存在\(0\)这一行。

我们发现,要想实现建立这个表,我们需要每次倍增长度。而最简单的倍增长度方法就是将两段不相交的区间合并起来。

所以我们可以得到如下公式:

\[st_{i,j}=min(st_{i,j-1},st_{i+2^{j-1},j-1}
\]

这样,我们就能完成建表

for(rg int i=1;i<=16;i++){ // 由计算器可得 log1e5 约为 17,但是这里循环16次已经够了。
for(rg int j=1;j+(1<<i)-1<=n;j++){
st[i][j]=min(st[i-1][j],st[i-1][j+(1<<(i-1))]);
}
}
  • 注:为了方便,我们常常把这个表“竖”过来。本篇中的代码一律如此

我们可以发现,建表的时间复杂度是\(O(nlogn)\)的

查询

我们由上表知道,想要查询\([l,r]\)的最值,只需求出

\[min(st_{l,log(len)},st_{r-2^{log(len)+1},log(len)})
\]

其中

\[len=r-l+1
\]

比如上方的数据,我们想要查询\([3,8]\)

我们只需要从\(3\)往后\(4\)个,\(8\) 往前\(4\)个,肯定能够完全覆盖这个区间

所以我们的查询开销是\(O(1)\)的

ans=min(st[(int)log2(len)][l],st[(int)log2(len)][r-(1<<((int)log2(len)))+1]);

至此,我们已经完成了全部内容

【算法学习笔记】RMQ问题与ST表的更多相关文章

  1. 某科学的PID算法学习笔记

    最近,在某社团的要求下,自学了PID算法.学完后,深切地感受到PID算法之强大.PID算法应用广泛,比如加热器.平衡车.无人机等等,是自动控制理论中比较容易理解但十分重要的算法. 下面是博主学习过程中 ...

  2. C / C++算法学习笔记(8)-SHELL排序

    原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...

  3. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  4. Johnson算法学习笔记

    \(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...

  5. Johnson 全源最短路径算法学习笔记

    Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...

  6. 【模板】RMQ问题的ST表实现

    $RMQ$问题:给定一个长度为$N$的区间,$M$个询问,每次询问$[L_i,R_i]$这段区间元素的最大值/最小值. $RMQ$的高级写法一般有两种,即为线段树和$ST$表. 本文主要讲解一下$ST ...

  7. RMQ问题及ST表

    RMQ(Range Minimum/Maximum Query)问题指的是一类对于给定序列,要求支持查询某区间内的最大.最小值的问题.很显然,如果暴力预处理的话复杂度为 \(O(n^2)\),而此类问 ...

  8. 算法学习笔记:最近公共祖先(LCA问题)

    当我们处理树上点与点关系的问题时(例如,最简单的,树上两点的距离),常常需要获知树上两点的最近公共祖先(Lowest Common Ancestor,LCA).如下图所示: 2号点是7号点和9号点的最 ...

  9. 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

    题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...

随机推荐

  1. 算法巩固的第一天-java冒泡排序算法

    自媒体萌新一枚,不对的地方各路大神可以指点指点!个人理解: 冒泡排序算法<插入排序算法<快速排序算法 /** * 冒泡排序算法 * @author sj * */ public class ...

  2. tar:归档中找不到 tar: 由于前次错误,将以上次的错误状态退出

    今天解压ZendStudio-10.0.0-x86.tar.gz,使用命令tar -zxvf ZendStudio-10.0.0-x86.tar.gz ./然后报下面错误tar: /tm: 归档中找不 ...

  3. 第三次Java实验报告

    Java实验报告 班级 计科二班 学号20188437 姓名 何磊 完成时间 2019/9/22 评分等级 实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档 ...

  4. Oracle - WITH AS -用于查询当月与上月数据

    注:在之前工作的时候,数据需要根据时间查询出当月值和上月的值. 语法: WITH A AS( SELECT * FROM TABLE ), B AS (SELECT * FROM TABLE)SELE ...

  5. 小记--------sparksql和DataFrame的小小案例java、scala版本

    sparksql是spark中的一个模块,主要用于进行结构化数据的处理,他提供的最核心的编程抽象,就是DataFrame.同时,sparksql还可以作为分布式的sql查询引擎. 最最重要的功能就是从 ...

  6. n*n矩阵 每行每列XOR为0(思维)

    题意:https://codeforc.es/contest/1208/problem/C 如题:就是给定一个数n,要你求一个n×n的矩阵,矩阵中的元素是 0 ~ n2-1 ,使得矩阵每一行和每一列的 ...

  7. C语言一行太长的换行处理

    转载:https://blog.csdn.net/baiqishijkh/article/details/79236202 在C语言程序编写中,我们有时会遇到一行代码太长而影响阅读或者出现与部分公司或 ...

  8. php 一些常用函数

    1.var_export() var_export — 输出或返回一个变量的字符串表示此函数返回关于传递给该函数的变量的结构信息,它和 var_dump() 类似,不同的是其返回的表示是合法的 PHP ...

  9. go 表单

    package main import ( "fmt" "io" "net/http" ) const form = `<html&g ...

  10. THUWC2020滚粗记

    \(Day-?\) 教练叫走了3个人,没叫我 感觉药丸,然后被告知pku没过,thu过了 神奇,然后就活了 后来在机房颓废,大声说笑被diss 当时感觉颓的有点过头,药丸 \(Day0\) 跟NC去T ...