单调栈与单调队列 |
您所在的位置:网站首页 › B3667086944 › 单调栈与单调队列 |
单调栈是一种内部元素具有单调性的栈,可以解决求“以某个值为最值的最大区间”等问题。
单调队列是一种内部元素具有单调性的队列,可以解决求“区间内最值”等问题。
单调栈
单调栈是一种内部元素具有单调性的栈,可以解决求“以某个值为最值的最大区间”等问题。 原理以下摘自 洛谷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 |