## [区间最值操作与区间历史最值详解](https://www.luogu.com.cn/blog/Hakurei-Reimu/seg-beats) 本文讲解了一种叫做 $Segment$ $Tree$ $Beats$ 的使用线段树维护区间最值操作的方法,和维护区间历史最值的常用手段。主要参考了了吉老师 $2016$ 年集训队论文(见文末参考资料)。 前置知识:**懒标记线段树**。 ### 区间最值操作 首先假设我们有一个序列 $A$。区间最值操作是指,给定 $l,r,k$,对于所有 $i\in[l,r]$ ,将 $A_i$变成 $\min(A_i,k)$ 或 $\max(A_i,k)$ 的一种操作。下面由一道例题引入。 [$HDU5306$. $Gorgeous$ $Sequence$](http://acm.hdu.edu.cn/showproblem.php?pid=5306) > 给出一个长度为 $n(n\leq 10^6)$ 的序列 $A$ 和 $m(m\leq 10^6)$ 次操作,每次操作为以下三种类型之一: > $1$. 给出 $l,r,k$,对于所有 $i\in[l,r]$,将 $A_i$ 变成 $\min(A_i,k)$ > $2$. 给出 $l,r$,求序列 $A$ 区间 $[l,r]$的 **最大值** > $3$. 给出 $l,r$,求 $\displaystyle \sum_{i=l}^{r}$​ 在这道题中,第一种操作就是 **区间最值操作**。我们发现,关于区间 **最大值的询问** 是可以使用 **带懒标记的线段树维护** 的,而 **区间和则不是很容易求出**,因为这 **不能在下传标记时快速更新答案**。 考虑到区间取 $\min$ 的操作只会对 **最大值超过 $k$ 的节点产生影响**,我们可以在这方面产生思路。为了使复杂度变低,线段树的一个节点要维护三个信息: - 区间最大值 $mx$ - 区间严格次大值 $se$ - 最大值的个数 $cnt$ 那么,一次区间 **最值操作$min$** 作用在这个节点上时,可以被分为以下三种情况: - $k≥mx$,此时该操作不会对当前节点产生影响,直接退出 - $se 按照上面描述的操作,我们应该沿着红色的边 $dfs$,最后 **在红色的节点上更新区间和并打上标记**。 这样做的复杂度可以证明是 $O(mlogn)$ 的。 ### 支持区间加减 我们在支持上一道例题中所有操作的同时,加入区间加操作。 此时有两种考虑这个问题的方法: - 套用上一题的做法,我们只需把标记换成二元组 $(add,v)$,表示将当前节点维护的区间先加上 $add$ 再与 $v$ 取最小值。**合并标记** 时,先考虑给当前节点加上一个标记,我们除了更新当前节点的区间加标记 $add$,还需要把它加到 $v$ 上;而给当前节点取最小值可以直接将标记对它取 $\min$。形式地说,当节点 $x$ 下传标记到它的儿子 $ch$ 时,我们把儿子的标记更新为 $(add_{ch}+add_x,\min(v_{ch}+add_x,v_x))$即可。 - 换一种新的思路,我们发现这种方法的本质是把线段树上每个节点维护的元素分成了 **最大值** 和 **非最大值** 这两类,并对它们分别维护。区间最大值标记只会打在 $se 给出一个长度为 $n(n\leq 5\times 10^5)$ 的序列 $A$ 和 $m(m\leq 5\times 10^5)$ 次操作,每次操作为以下六种类型之一: > 1. 给出 $l,r,k$,对于所有 $i\in[l,r]$,将 $A_i$ 加上 $k$ > 2. 给出 $l,r,k$,对于所有 $i\in[l,r]$,将 $A_i$ 变成 $\max(A_i,k)$ > 3. 给出 $l,r,k$,对于所有 $i\in[l,r]$,将 $A_i$ 变成 $\min(A_i,k)$ > 4. 给出 $l,r$, 求 $\sum_{i=l}^{r}$ > 5. 给出 $l,r$,求序列 $A$ 区间 $[l,r]$ 的最大值 > 6. 给出 $l,r$,求序列 $A$ 区间 $[l,r]$ 的最小值 在这道题中,区间取 **最大值** 和 **最小值** 的操作同时出现了。虽然我们同样可以套用**第一道例题**的方法,维护区间加、区间取 $\max$,区间取 $\min$ 三个标记,但实现起来会很复杂(可以参考 [$OI-wiki$ 上的题解](https://oi-wiki.org/ds/seg-beats/#bzoj4695))。这里我们可以仍考虑通过划分数域 **将区间最值操作转化为区间加减**。 应这道题的需要,我们将一个区间的元素划分为 **最大值**、**最小值**和 **其他值**三种。首先在每个节点上肯定要维护区间和 $sum$、区间最大值 $mx$ 和最小值 $mi$ 的信息,同时我们也要维护次大值 $semx$、次小值 $semi$ 和最大值最小值的个数 $cmx$,$cmi$。我们分别讨论题目中的三种修改操作。 - 对于加减操作,在线段树上定位区间后直接对三类值同时加上 $k$ - 对于取最小值操作,在线段树上暴力搜索找到 $semx