Codeforces Round 1074

A. Perfect Root

相異なる正整数 $n$ 個を出力すればよいです.

B. Prefix Max

$1+\binom{n}{2}$ 通りすべての方法を試しても間に合います.

C. Shifted MEX

$l,l+1,\ldots,r$ という連番が $a$ に現れている長さの最長です.

D. OutOfMemoryError

操作履歴を持っておくと,操作回数に比例する計算量で巻き戻せます.

E. The Robotic Rush

初期位置からいくつ左にずれると死亡,いくつ右にずれると死亡.という量を二分探索などで求めておきます.

左右それぞれ起こりやすいものから順に並べておくと,時刻ごとに,先頭にある死亡判定イベントを処理する形でよくなります.

F. BattleCows

勝者が新しいノードを作ると考えて木を作っておきます(セグメント木のようにインデックスをつけると簡単).

各ノードにおいて,変更が来なかった場合の xor を求めておきます.

すると,クエリごとに,葉から登りながらそのノードに来た時点での xor および,対象の牛が何番目であるかを計算できます.

G. Mixing MEXes

$i$ ごとに 「すべての操作にわたる $\mathrm{MEX}(a_i)$ の和」を求めます.

$a_i$ から運び出す操作,持ってくる操作,$a_i$ が変更されない操作.などに対する計算を行います.

運び出す操作については,「列から $1$ 要素削除したとき mex はどうなりますか?」という計算です.初期状態の mex を $x$ として,削除する要素を $y$ としたとき,$y<x$ かつ $y$ の出現頻度が $1$ 回のときには削除後の mex は $y$,それ以外では mex は $x$ のままです.

持ってくる操作をしたときは,初期状態の mex を $x$ として,$x$ を持ってきた場合だけが $x$ 以外の値に変化します.そのときの mex およびその方法の個数などを適切に計算します.

全操作の個数を最初に求めておいて,上述の計算をしながら処理済の操作の個数を引いていくと,$a_i$ が変更されない場合の操作の個数も分かります.

やや計算ミスの起こりやすい作業量が多めだと思います.

H. BattleCows 2

敗北回数が $k$ 回以下という条件です.敗北というのは「左側に負ける」「右側に負ける」の $2$ 種があります.

「右側に負ける」という条件を整理すると,$j$ に負けるときには $a_1+\cdots+a_{j-1}<a_j$ が成り立つことが必要であることが分かります.これは $i$ の挿入前・挿入後の位置関係によらない必要条件です.

このような場所では prefix sum が $2$ 倍より大きくなります.よってそのような場所の候補が $O(\log \sum a_i)$ 個となって,少ないことが分かります.

これらを大事な $j$ として,事前に列挙しておきます.

これを踏まえて,$a_i$ を挿入する位置を固定したときの判定として,

  • 大事な $j$ について,「$j$ が右側で $j$ に負ける」かどうかをチェックする.
  • $i$ が左側に負けるかどうかをチェックする.

ことで敗北回数が求められます.

これを踏まえて.$i$ ごとに個別に答を求めます.$i$ および大事な $j$ のところなどで適切に座圧して,区間ごとに答を求めます.

座圧区間ごとに,「右側に負ける」イベントの回数は求まります.これが $k-1$ 以下または $k+1$ 以上の場合はそこで判定終了で,区間長を答に加算するなどします.

ちょうど $k$ 回の場合には,さらに左に負けるかどうかを調べることになります.これは適当な二分探索で求まります.

以上を適切に実装すると,全体で $O(n(\log \sum a_i + \log n))$ などの計算量で解けます.

CodeForces
スポンサーリンク
シェアする
maspyをフォローする
maspyのHP
タイトルとURLをコピーしました