006 - Smallest Subsequence(★5) Editorial by ngtkana


ヒープを使った、最悪 \(\Theta(N \lg N)\) 時間の解法です。

左から順に走査し、文字とインデックスの組をヒープに入れていきます。\(N - K + 1, N - K + 2, \dots, N - K\) 個入れ終わったときにヒープから最小の文字を取り出します。それをそのまま使うと、前回の位置よりも前になることがあるので、適切なものが出てくるまで繰り返します。これは必ずいつか成功します。

use proconio::{fastout, input};
use std::{cmp::Reverse, collections::BinaryHeap};

#[fastout]
fn main() {
    input! {
        n: usize,
        k: usize,
        s: String,
    }
    let mut heap = BinaryHeap::new();
    let mut next = 0;
    let mut ans = String::new();
    for (i, c) in s.chars().enumerate() {
        heap.push(Reverse((c, i)));
        if n <= i + k {
            loop {
                let Reverse((d, j)) = heap.pop().unwrap();
                if next <= j {
                    next = j + 1;
                    ans.push(d);
                    break;
                }
            }
        }
    }
    println!("{}", ans);
}

提出 (14 ms): https://atcoder.jp/contests/typical90/submissions/28303640

posted:
last update: