1. 普通做法

  1. ST 表:\(O(n\log n+q)\)
  2. Sqrt Tree:\(O(n\log\log n+q)\)
  3. 线段树 / zkw 线段树:\(O(n + q\log n)\) .
  4. 猫树:\(O(n\log n+q)\)
  5. 单调栈:\(O(q\log q+q\log n)\)

2. Four Russian 算法

先分块,假设块长为 \(B\) .

预处理整块的最小值,把每个整块连起来然后开个 ST 表,对每个零散块也开 ST 表

我们可以将询问区间划分为不超过 \(1\) 个整块数组上的连续块区间和不超过 \(2\) 个原数组上的整块内的连续区间。显然这些问题我们通过 ST 表上的区间查询解决。

取 \(B=\log n\),预处理复杂度就是 \(O(n\log\log n)\) 的,常数较大 .

一个小优化:我们发现,在询问的两个端点属于不同的块的时候,块内的询问是关于每一块前缀或者后缀的询问,用 \(O(n)\) 预处理答案,这样子我们只需要在询问的时候进行至多一次 ST 表上的查询操作了 .

3. 随机数据的一种做法

题目:由乃救爷爷

分块,设块长为 \(B\),当然先预处理每个整块的最小值

若区间跨过了多个块,那么整块可以 st 表处理,零散块可以预处理每个块内的前缀后缀最小值处理 .

若区间左右端点正好在同一个块内,暴力扫,复杂度 \(O(B)\) 比较高,但注意到询问区间随机的情况下,不难得出两个端点在同一个块内的概率是 \(\dfrac Bn\) .

所以这种情况期望复杂度 \(O\left(\dfrac{B^2}n\right)\) .

当 \(b\) 至少为 \(O(\log n)\) 时,预处理整块 st 表复杂度 \(O\left(\dfrac nB\log\dfrac nB\right)\) 不超过 \(O(n)\) .

当 \(b\) 至多为 \(O(\sqrt n)\) 时,预处理整块 st 表复杂度 \(O\left(q\dfrac Bn\right)\) 不超过 \(O(q)\) .

所以 \(b\) 取 \(O(\log n)\) 到 \(O(\sqrt n)\) 之间的一个值即可 .

当 \(b=\sqrt n\) 时,直接暴力预处理所有可能区间的最大值即可,复杂度不变,常数可能小一些 .

4. 有关转 LCA 的做法

1.1. RMQ 转 LCA 再转 ±1RMQ(RMQ 标准算法)

先 \(O(n)\) 建序列的笛卡尔树,不难发现两个点之间的最小值就是它们的 LCA 的权值 .

使用基于 RMQ 的树上 LCA 算法,发现笛卡尔树的欧拉序相邻两个节点深度差必然为 \(\pm 1\) .

我们假设我们在 word-RAM model 中 .

由于相邻两个元素之差为 \(1\),那么长度为 \(n\) 的本质不同的序列只有 \(2^n\) 个 .

考虑将序列按照 \(\dfrac12\log n\) 分段,在 word-RAM model 中,一个常见的假设是字长 \(w\ge \log n\),注意到长度为 \(\dfrac 12\log_2 n\) 的本质不同的数列只有 \(O(\sqrt n)\) 个,我们可以枚举所有可能的情况,并枚举左右端点,这可以在 \(O(\sqrt n\log^2 n)\) 的时间复杂度内完成 .

因为一个数列长度为 \(n\) 的数列可以用二进制串编码(对于一个序列 \(a\),其二进制串编码的第 \(j\) 位为 \([a_j<a_j+1]\))

对于分成的 \(O\left(\dfrac{n}{\log n}\right)\) 段,使用 ST 表维护 .

从而对于零散块来说,查表即可得出答案,我们也就得到了 \(O(n)\) - \(O(1)\) 的求解一般 RMQ 问题的解法

好像可以把块内用线段树维护,整块用 st 表,或许会更快 .

1.2. 一个优化

对于每个块维护一个单调队列,再把单调队列状压 .

这份提交 好像是这种写法

2. RMQ 转 LCA 然后 tarjan 求 LCA

RMQ 转 LCA 上面已经说过了,tarjan 求 LCA 是可以优化到线性的,给两个链接:

离线并查集是 \(O(n\alpha(n))\) 的,本质相似,实际跑起来会快一些 .

3. RMQ 转 LCA 然后 Schieber Vishkin algorithm 求 LCA

同 \(2\),Schieber Vishkin algorithm 的描述可以在 这里 找到

5. 一个 \(O(n\log^*n)\) - \(O(1)\) 的算法

考虑左右端点在同一块内的时候,把小块当成一个整序列,也是分块,从而预处理时间 \(T(n)\) 满足

\[T(n)=O(n)+\dfrac{n}{\log n}T(\log n)
\]

不难发现,递归的深度是 \(O(\log^* n)\)

从而预处理时间复杂度 \(O(n\log ^* n)\),询问时间复杂度 \(O(\log^* n)\)

我们不妨假设每层大块长都是 \(2\) 的幂,这样分出来的小段长都是一样的:\(\log n,\log\log n,\cdots,1\)

对于一个询问,若其区间长度是 \(L\),我们找出第一个小段长 \(\le L\) 的层,可以发现这个询问一定可以在这一层或者上一层 \(O(1)\) 回答出来。这样只要对每个询问长度预处理找的层就可以做到 \(O(1)\) 询问了 .

关于静态 RMQ 问题的更多相关文章

  1. POJ 3264 Balanced Lineup 【ST表 静态RMQ】

    传送门:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total S ...

  2. ST表(求解静态RMQ问题)

    例题:https://www.acwing.com/problem/content/1272/ ST表类似于dp. 定义st[i][j]表示以i为起点,长度位2^j的一段区间,即[ i , i + 2 ...

  3. [数据结构]RMQ问题小结

    RMQ问题小结 by Wine93 2014.1.14   1.算法简介 RMQ问题可分成以下2种 (1)静态RMQ:ST算法 一旦给定序列确定后就不在更新,只查询区间最大(小)值!这类问题可以用倍增 ...

  4. 数据结构RMQ

    RMQ算法介绍 RMQ算法全称为(Range Minimum/Maximum Query)意思是给你一个长度为n的数组A,求出给定区间的最值的下标.当然我们可以采用枚举,但是我们也可以使用线段树来优化 ...

  5. OI总结(垃圾排版就忽略了吧)

    学OI一年了,到现在联赛所需要的知识已经基本学完了.现在,有必要回过头来,总结总结自己一年来学到的知识以及得到的经验教训. 基础 语言基础 C++的语言基础啥的就略了吧. 算法复杂度分析 O:复杂度的 ...

  6. Luogu P2880 [USACO07JAN]平衡的阵容Balanced Lineup (ST表模板)

    传送门(ST表裸题) ST表是一种很优雅的算法,用于求静态RMQ 数组l[i][j]表示从i开始,长度为2^j的序列中的最大值 注意事项: 1.核心部分: ; (<<j) <= n; ...

  7. 【做题记录】USACO gold * 50(第一篇)

    orz xhk 5/50 1597: [Usaco2008 Mar]土地购买 $ f[i]=min(f[j]+x[i]*y[j+1]) $ 然后斜率优化 1699: [Usaco2007 Jan]Ba ...

  8. 【做题记录】USACO silver * 50(第一篇)

    由于我太菜,决定按照AC人数从小到大慢慢做. BZOJ开了权限号真的快了好多诶~ 29/50 1606: [Usaco2008 Dec]Hay For Sale 购买干草 背包dp 1610: [Us ...

  9. BZOJ 3166 HEOI2013 ALO 可持久化trie+st表

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3166(洛谷上也有) 题意概述: 给出一个序列,对于一个区间,其权值为区间中的次大值亦或区 ...

随机推荐

  1. JavaScript 任务池

    JavaScript 任务池 本文写于 2022 年 5 月 13 日 线程池 在多线程语言中,我们通常不会随意的在需要启动线程的时候去启动,而是会选择创建一个线程池. 所谓线程池,本意其实就是(不止 ...

  2. mybatis plus 使用 SQL 保留字(关键字)

    MybatisPlus:使用SQL保留字(关键字)的操作 必须要手动在 entity 的字段上加注解,否则最终会报错,因为 mybatis 或者 mybatis plus 不会自动处理

  3. 【万字长文】使用 LSM Tree 思想实现一个 KV 数据库

    目录 设计思路 何为 LSM-Treee 参考资料 整体结构 内存表 WAL SSTable 的结构 SSTable 元素和索引的结构 SSTable Tree 内存中的 SSTable 数据查找过程 ...

  4. v87.01 鸿蒙内核源码分析 (内核启动篇) | 从汇编到 main () | 百篇博客分析 OpenHarmony 源码

    本篇关键词:内核重定位.MMU.SVC栈.热启动.内核映射表 内核汇编相关篇为: v74.01 鸿蒙内核源码分析(编码方式) | 机器指令是如何编码的 v75.03 鸿蒙内核源码分析(汇编基础) | ...

  5. jQuery基础入门+购物车案例详解

    jQuery是一个快速.简洁的JavaScript代码库(或JavaScript框架).jQuery设计的宗旨是"write Less,Do More",即倡导写更少的代码,做更多 ...

  6. Django对接支付宝Alipay支付接口

    最新博客更新见我的个人主页: https://xzajyjs.cn 我们在使用Django构建网站时常需要对接第三方支付平台的支付接口,这里就以支付宝为例(其他平台大同小异),使用支付宝开放平台的沙箱 ...

  7. HTML5续集

    H5 input新增属性 1.color 拾色器 2.Email 电子邮件 3.tel 电话 4.datetime-local 本地日期和时间 5.range 范围 6.url 路径,地址 7.sea ...

  8. .NET性能优化-推荐使用Collections.Pooled(补充)

    简介 在上一篇.NET性能优化-推荐使用Collections.Pooled一文中,提到了使用Pooled类型的各种好处,但是在群里也有小伙伴讨论了很多,提出了很多使用上的疑问. 所以特此写了这篇文章 ...

  9. pytorch初学

    (pytorch_gpu) D:\pytorch-text>pythonPython 3.7.9 (default, Aug 31 2020, 17:10:11) [MSC v.1916 64 ...

  10. 有关安装pycocotools的办法

    1,首先需要安装Visual C++ 2015构建工具,地址https://download.microsoft.com/download/5/f/7/5f7acaeb-8363-451f-9425- ...