单调栈与单调队列

您所在的位置:网站首页 B3667086944 单调栈与单调队列

单调栈与单调队列

2024-06-12 12:27| 来源: 网络整理| 查看: 265

单调栈是一种内部元素具有单调性的栈,可以解决求“以某个值为最值的最大区间”等问题。 单调队列是一种内部元素具有单调性的队列,可以解决求“区间内最值”等问题。 单调栈

单调栈是一种内部元素具有单调性的栈,可以解决求“以某个值为最值的最大区间”等问题。

原理

以下摘自 洛谷B3666 求数列所有后缀最大值的位置 题目描述:

给定一个数列 \(a\),初始为空。有 \(n\) 次操作,每次在 \(a\) 的末尾添加一个正整数 \(x\)。

每次操作结束后,请你找到当前 \(a\) 所有的后缀最大值的下标(下标从 1 开始)。一个下标 \(i\) 是当前 \(a\) 的后缀最大值下标当且仅当:对于所有的 \(i < j \leq |a|\),都有 \(a_i > a_j\),其中 \(|a|\) 表示当前 \(a\) 的元素个数。

考虑用一个栈维护当前数列所有后缀最大值的位置(即下标),初始时栈为空。

易证栈中元素对应的数是单调递减的,因此称为单调栈。

考虑 \(a\) 加入一个元素 \(a_i\) 时单调栈将如何变化。

若栈顶元素 \(j\) 满足 \(a_j \le a_i\),则此时 \(a_j\) 不再是后缀最大值,因此弹出 \(j\)。

若栈顶元素 \(j\) 满足 \(a_j > a_i\),则此时 \(a_j\) 仍然是后缀最大值,不操作。

由后缀最大值的定义知 \(a_i\) 一定是后缀最大值,\(i\) 入栈。

由于单调栈中的元素对应的数单调递减,所以应删去的元素仅存在于栈顶,因此只需要重复执行第一步直到 \(a_j > a_i\) 即可。

类似地,单调栈可以维护数列所有后缀最值或前缀最值,这是单调栈维护的本质信息。

实现

使用 STL 的 std::vector 容器而非 std::stack 实现单调栈,原因是 std::stack 时空常数巨大且 std::vector 支持 std::stack 的全部功能。

以下为核心代码:

std::vector s; for (int i = 1; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3