线性RMQ——四毛子算法

$\text{RMQ}$

$\text{RMQ(Range Minimum/Maximum Query)}$,区间最值查询问题。

形式化来说,给出长为 $n$ 的数组以及 $m$ 组形如 $l,r$ 的询问,对于每组询问,需要回答区间 $[l,r]$ 里的最值。

有关四毛子算法

四毛子算法,一种分块的应用,也是一种能实现 $O(n)-O(1)$ 进行区间 $\text{RMQ}$ 的算法。

相比之下,它会比常见的其他算法时间要优,诸如什么 $O(n\log n)-O(1)$ 的 $\text{ST}$ 表,$O(n),O(\log n)$ 的线段树。但是常数相比 $\text{ST}$ 表会逊色一些。

做法

考虑设定阈值 $B=\log n$。把序列分成 $\frac{n}{B}$ 个块,每个块的长度为 $B$。

之后我们分两种区间考虑(询问的左右端点分别记为 $l,r$):

  1. 询问的左右端点不在同一个块中

    整块:利用 $\text{RMQ}$ 预处理出第 $l\to r$ 个块的最小值,时间复杂度 $O(\frac{n}{B} \log n)$。

    散块:维护块内前缀最小值与后缀最小值。

  2. 询问的左右端点在同一个块中

    每个块中维护一个单调栈,遍历到一个点时记录当前单调栈中节点的集合(由于块长为 $\log n$,所以一个 $\text{int}$ 就能存下)。时间复杂度 $O(n)$。

    查询对于 $r$ 的二进制集合状态,某位后面的第一个 $1$ 在哪一位即可(可以使用 `__builtin_clz()`)。

posted @ 2023-07-19 19:28  徐子洋  阅读(235)  评论(0)    收藏  举报  来源