一、 算法&数据结构
1. 描述
单调栈可以用O(n)的时间求出数组中每个元素作为最大/最小值能管辖的左右范围;其中包括遇到相等值跳过还是停下。
2. 复杂度分析
- 初始化, O(n)
- 查询,O(1)
3. 常见应用
4. 常用优化
二、 模板代码
1. 前后都越过相等值的单调栈
例题: CF547B. Mike and Feet

#[allow(unused)]
use std::collections::*;
use std::io::{BufRead, BufWriter, Write};
#[allow(unused)]
fn main() {
let sin = std::io::stdin();
let scan = &mut Scanner::new(sin.lock());
let sout = std::io::stdout();
let out = &mut BufWriter::new(sout.lock());
run(scan, out);
}
pub struct Scanner<R> {
reader: R,
buffer: Vec<String>,
}
impl<R: ::std::io::BufRead> Scanner<R> {
pub fn new(reader: R) -> Self {
Self {
reader,
buffer: vec![],
}
}
pub fn token<T: ::std::str::FromStr>(&mut self) -> T {
loop {
if let Some(token) = self.buffer.pop() {
return token.parse().ok().expect("Failed parse");
}
let mut input = String::new();
self.reader.read_line(&mut input).expect("Failed read");
self.buffer = input.split_whitespace().rev().map(String::from).collect();
}
}
}
#[allow(unused)]
pub fn solve1(scan: &mut Scanner<impl BufRead>, out: &mut impl Write) {
let n = scan.token::<usize>();
let mut a = vec![0i32; n];
let mut ls = vec![-1i32; n];
let mut rs = vec![n as i32; n];
let mut st1 = vec![0i32; 0];
let mut st2 = vec![0i32; 0];
for i in 0..n {
a[i] = scan.token::<i32>();
while st1.len() > 0 && a[*st1.last().unwrap() as usize] >= a[i] {
st1.pop();
}
if st1.len() > 0 {
ls[i] = *st1.last().unwrap();
}
st1.push(i as i32);
while st2.len() > 0 && a[*st2.last().unwrap() as usize] > a[i] {
rs[st2.pop().unwrap() as usize] = i as i32;
}
st2.push(i as i32);
}
let mut ans = vec![0i32; n];
for i in 0..n {
let len = (rs[i] - ls[i] - 1 - 1) as usize;
ans[len] = ans[len].max(a[i])
}
for i in (0..n - 1).rev() {
ans[i] = ans[i].max(ans[i + 1])
}
for v in ans {
write!(out, "{} ", v).ok();
}
}
pub fn solve(scan: &mut Scanner<impl BufRead>, out: &mut impl Write) {
let n = scan.token::<usize>();
let mut a = vec![0i32; n];
for i in 0..n {
a[i] = scan.token::<i32>()
}
let (l, r) = MonoStack::new(&a).get_true_bound_as_min();
let mut ans = vec![0i32; n];
for i in 0..n {
let len = (r[i] - l[i] - 2) as usize;
ans[len] = ans[len].max(a[i])
}
for i in (0..n - 1).rev() {
ans[i] = ans[i].max(ans[i + 1])
}
for v in ans {
write!(out, "{} ", v).ok();
}
}
pub fn run(scan: &mut Scanner<impl BufRead>, out: &mut impl Write) {
solve(scan, out)
}
#[allow(unused)]
pub struct MonoStack {
a: Vec<i32>,
}
impl MonoStack {
pub fn new(a: &Vec<i32>) -> Self {
Self { a: a.clone() }
}
pub fn get_bound_as_min_left_over_and_right_stop(&self) -> (Vec<i32>, Vec<i32>) {
let a = &(self.a);
let n = a.len();
let mut l = vec![-1i32; n];
let mut r = vec![n as i32; n];
let mut st = Vec::new();
for (i, &v) in a.iter().enumerate() {
while st.len() > 0 && a[*st.last().unwrap() as usize] >= v {
r[st.pop().unwrap() as usize] = i as i32;
}
if st.len() > 0 {
l[i] = *st.last().unwrap();
}
st.push(i as i32);
}
return (l, r);
}
pub fn get_bound_as_min_left_stop_and_right_over(&self) -> (Vec<i32>, Vec<i32>) {
let a = &self.a;
let n = a.len();
let mut l = vec![-1i32; n];
let mut r = vec![n as i32; n];
let mut st = Vec::new();
for (i, &v) in a.iter().enumerate() {
while st.len() > 0 && a[*st.last().unwrap() as usize] > v {
r[st.pop().unwrap() as usize] = i as i32;
}
if st.len() > 0 {
l[i] = *st.last().unwrap();
}
st.push(i as i32);
}
return (l, r);
}
pub fn get_true_bound_as_min(&self) -> (Vec<i32>, Vec<i32>) {
let (l, _) = self.get_bound_as_min_left_over_and_right_stop();
let (_, r) = self.get_bound_as_min_left_stop_and_right_over();
return (l, r);
}
pub fn get_bound_as_max_left_over_and_right_stop(&self) -> (Vec<i32>, Vec<i32>) {
let a = &(self.a);
let n = a.len();
let mut l = vec![-1i32; n];
let mut r = vec![n as i32; n];
let mut st = Vec::new();
for (i, &v) in a.iter().enumerate() {
while st.len() > 0 && a[*st.last().unwrap() as usize] <= v {
r[st.pop().unwrap() as usize] = i as i32;
}
if st.len() > 0 {
l[i] = *st.last().unwrap();
}
st.push(i as i32);
}
return (l, r);
}
pub fn get_bound_as_max_left_stop_and_right_over(&self) -> (Vec<i32>, Vec<i32>) {
let a = &self.a;
let n = a.len();
let mut l = vec![-1i32; n];
let mut r = vec![n as i32; n];
let mut st = Vec::new();
for (i, &v) in a.iter().enumerate() {
while st.len() > 0 && a[*st.last().unwrap() as usize] < v {
r[st.pop().unwrap() as usize] = i as i32;
}
if st.len() > 0 {
l[i] = *st.last().unwrap();
}
st.push(i as i32);
}
return (l, r);
}
pub fn get_true_bound_as_max(&self) -> (Vec<i32>, Vec<i32>) {
let (l, _) = self.get_bound_as_max_left_over_and_right_stop();
let (_, r) = self.get_bound_as_max_left_stop_and_right_over();
return (l, r);
}
}
三、其他
四、更多例题
五、参考链接