結果
| 問題 |
No.2930 Larger Mex
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-01-23 02:39:05 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 44 ms / 2,000 ms |
| コード長 | 1,735 bytes |
| コンパイル時間 | 20,309 ms |
| コンパイル使用メモリ | 400,488 KB |
| 実行使用メモリ | 20,836 KB |
| 最終ジャッジ日時 | 2025-01-23 02:39:38 |
| 合計ジャッジ時間 | 27,197 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 50 |
ソースコード
use proconio::input;
use std::collections::HashSet;
/// https://yukicoder.me/problems/no/2930
/// https://yukicoder.me/problems/no/2930/editorial
///
/// MEXの性質を考える
/// ri = mex(Ai..Ari)>=Mとなる最小の整数とする
/// そのとき、mex(Ai..Ari)<=mex(Ai..Ari+1)<=...<=mex(Ai..An)が成り立つ。
///
/// あとは、尺取り法で ri を求めて、左端: l を動かしていく
/// ri が求まるたびに、k = ri-l+1,...,n-l+1 の答えに +1 していく
/// これは、imos法で高速に求めることができる
fn main() {
input! {
n: usize,
m: usize,
a: [usize; n],
}
if m == 0 {
println!(
"{}",
(1..=n)
.rev()
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join("\n")
);
return;
}
let mut k_imos = vec![0_i64; n + 2];
let mut cnt = vec![0; m];
let mut set = HashSet::new();
let mut r = 0;
for l in 0..n {
while r < n && set.len() < m {
if a[r] < m {
set.insert(a[r]);
cnt[a[r]] += 1;
}
r += 1;
}
if set.len() < m {
break;
}
k_imos[r - l] += 1;
k_imos[n - l + 1] -= 1;
if a[l] < m {
cnt[a[l]] -= 1;
if cnt[a[l]] == 0 {
set.remove(&a[l]);
}
}
}
for i in 1..n + 1 {
k_imos[i + 1] += k_imos[i];
}
println!(
"{}",
k_imos
.iter()
.skip(1)
.take(n)
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join("\n")
)
}