Codeforces Round 1061

A. Pizza Time

$(1,1,x-2)$ のように分割する戦略で,半分くらいとれます.あとは端数調整を丁寧に.

相手は自分以上とり続けることから最適性が証明できます.

B. Strange Machine

クエリごとに独立に解きます.

タイプ B がなければ自明.タイプ B があるときはそのままシミュレーションすれば,$O(N\log a)$ ステップで済みます.

C. Maximum GCD on Whiteboard

$x$ を $d$ の倍数にできるかを判定します.

最初から $d$ の倍数なら OK.

そうでないとき,$x=3d$ なら OK.

そうでないとき,$x$ は $d+d+2d=4d$ 以上でなければなりません.

$(d,-,2d)$, $(d,-,3d)$, $(d,-,4d)$ などを調べると,$4d$ 以上なら全部できることも分かります.

これを踏まえると,各 $d$ に対して,$d$ の倍数にするためのコストを計算できます.

約数への点加算や適当な区間加算に帰着されます.

D. Find the Last Number

0-th, 1-th, 2-th, … bit の順に見て Trie を考えて,$p_N$ と同じノードに居るインデックス全体を持ちます.クエリは保持しているインデックスと $x=2^k$ の形について行います.

保持するインデックスの個数が $1/2$ 倍の切り上げになっていって,クエリ回数が $2N$ を少し超える可能性があると思って悩んでしまいましたが $N$ 自身はクエリしないので大丈夫みたいです.

E. Best Time to Buy and Sell Stock

AC 人数のわりにややこしい解法になってしまっているかも.

「後手がスコア $t$ 以上を達成できるか?」という判定問題を考えてみます.

これは次のようにグラフの問題と言い換えられます:

$i<j$ かつ $b_j-b_i\geq t$ となる $i,j$ を辺で結んだグラフを考える.削除とロックを繰り返して最終的にある辺の両端点がロックされていれば後手が勝利する.

このゲームの勝利条件は次の通りです:

  • 先手が削除した時点で,次数 $2$ 以上の点が残っていれば後手が勝ち.そうでなければ先手が勝ち.
  • 後手の必勝戦略:次数 $2$ の点を最初にロック.次の手番で勝利を確定する.
  • 先手の必勝戦略:グラフは孤立点とマッチングからなる.相手が選んだ点にマッチしている点が残っているなら直後にそれを削除する.

すると,元のゲームでのスコアは次のようになります.

  • 先手が削除した時点で,次のようにスコアが決まる:「ある頂点の近傍の辺のスコアのうち大きいものから $2$ 番目」の最大値.

答を計算するには,まず先手が削除をしなかった場合の答を求めます.その場合の答を阻止しようとすると,先手番の戦略は高々 $3$ 通りになるので,それを試せばよいです.

各頂点に対してスコアの大きな $3$ 頂点だけ残せばよくて,明示的にグラフを構築して何かをやるというタイプの実装でもよかったですね.

F2. Strange Operation (Hard Version)

代わりに逆順列 $A$ を考えると,操作は次のようになります:

  • $\min\{A_{i-2},A_{i-1},A_{i}\}=A_i$ となる $i$ を選び,この $3$ 項を適切に rotate する.

さらに,$A$ の prefix について順に答えを求めていく次の貪欲法が最適解を与えることが証明できます.

  • 操作可能な最小の $i$ を選び操作することを繰り返す.

これで最適なことは,$A$ の最小値を追加することを考えて帰納法をすれば示せると思います(細部は確認しきれていない).

あとはこのシミュレーションを高速にします.次のように言い換えて処理しました.

  • $ANS$ が空の状態から始める.$i=0,1,2,\ldots$ 順に次を行う.
  • $x=A[i]$ とする.$ANS$ の末尾に $x$ を追加したあと,操作で可能な限り $x$ を $2$ つ手前に移動させる.

すると必要なのは $x$ を $ANS$ の適当な位置に挿入することの繰り返しになります.

挿入するための二分探索なども必要で,私は区間 $\min$ のとれる平衡二分木を使いました.

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