けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

AtCoder AGC 063 B - Insert 1, 2, 3, ... (青色, 600 点)

セグ木とか必要なくて、本当に単純な実装で解けるの面白い

問題

制約

  •  1 \le N \le 5 \times 10^{5}

考えたこと

まずは、生成可能であるための分かりやすい特徴付けを考えようと思った。数列の生成手順が、いかにも入れ子構造をしているので、カッコ列を連想した。

カッコ列の連想から、次の判定手順が自然に得られた。


スタックを用意する。

数列を後ろから見ていくことにする。今見ている要素が  v であるとき

  •  v \gt 1 ならば、スタックに  v を挿入する
  •  v = 1 ならば、階段になっている限りスタックを pop していく (たとえば、スタックが top から順に 2, 3, 4, 6, ... だとしたら、 v = 1 に対して操作したあとのスタックは top から順に 6, ... となる)

最終状態において、スタックが空であることが、生成可能であるための必要十分条件である。


これで判定は解けた。

数え上げ

一般に、区間  \lbrack l, r) が生成可能ならば、 i = l+1, l+2, \dots, r-1 に対して区間  \lbrack l, i) も生成可能である。

よって、上に述べたようなスタックの処理をしながら、


  •  A_{l} = 1 であるような  l に対して
  • スタック操作後のスタックの先頭要素の添字を  r として (空なら  N として)、 r - l を答えに合算していく

とすることで問題が解ける。計算量は  O(N) となる。

コード

atcoder.jp