Educational Codeforces 179

スポンサーリンク

A. Energy Crystals

貪欲に大きくします.最小値を中央値の $2$ 倍より $1$ 大きくできます.

こうして作った方法は,ほかの方法で作ったものより,ソートして項別に見て大きいという感じで貪欲の正当性を確認できます.

B. Fibonacci Cubes

読解が大変,絵がヒント.

結局大きい方から $2$ つ入れられれば全部入ります.上に積んだ場合,正方形同士の隙間の部分に残りを平面的に詰め込めます.横に並べた場合,小さい方の上面に並べられて,このときの高さは最大高さ以下なので大丈夫です.

C. Equal Values

操作によってつくられたもの以外は,空または区間をなします(prefix, suffix 以外ということなので).結局連長圧縮してひとつの成分を残す形だけ調べればよいです.

D. Creating a Schedule

$6$ 個の class No がありますが,$2$ 個の場合の最大値を $5$ 回繰り返せます(単に交互に並べる).

$2$ 個の場合を考えます.移動前後を $a_i, b_i$ とします.得点は $|a_i-b_i|$ ですが,絶対値で和を最大化したいので,$a_i-b_i$ または $-a_i+b_i$ を選ぶとしてよいです.

すると結局,$a_i,b_i$ の合計 $n$ 個をプラスでとって合計 $n$ 個をマイナスでとることになります.これらの $n$ 個ずつが,貪欲になるように調整します(入力の列を $2$ つコピーしてつなげたときに,ソートして小さい $n$ 個がマイナス,大きい $n$ 個がプラスとして選ばれるようにするということ).

E. Changing the String

文字列の先頭から見ていきます.

  • B の場合
    • 「B → A」がある場合,使うとしてよいです.「B → C → A」を使いながら「B → A」を違う用途(C → B → A)で使うパターンは組み替えられるからです.また,「B → A → X」のように 「B → A」に依存する後の処理は考えないでよいので,クエリ列の一番最初のものを使ってしまってよいです.
    • そうでない場合,「B → C → A」があるならば使います.これは「C → A」が後ろに来る唯一のパターンなので,「C→A」は最後のものを使うとしてよく,「B → C」もその手前のうちなるべく後ろにあるものを使えばよいです.
  • C の場合
    • 「C → A」がある場合,最初のそれを使います.
    • そうでない場合,まず「C → B」を使います.これは何かの後に置かれる可能性がない手順なので,先頭のものを使うとしてよいです.あとは「B の場合」と同じことをすればよいです.

F. Puzzle

周長 $P$ を固定した場合の面積 $S$ の最小・最大を考えます.

最大は正方形に最も近い長方形の場合です.周長は bounding box の周長以上なので,boundinb box を固定して考えると明らかです.

最小は,真横にひたすら並べた場合です.正方形 $n$ 個の場合,隣接組が $n-1$ 個以上できて,周長は $4n-2(n-1)$ 以下になるからです.

この間が全部作れます.

まず,bounding box の大きさを探索します.$(H,W)$ であって,$H+W=P/2$ かつ $H+W-1\leq S\leq HW$ となるものをとります.上記の必要条件のもと存在します.

あとは,bounding box の大きさを変えずに周長もそれを超えないように正方形を詰め込んでいけばよいです.

$1$ 行目,$1$ 列目を満たしたあと,辞書順に置いていけばよいです.

入力では $P, S$ ではなくその比が与えられているだけなので,これは適当な範囲(面積が $50000$ 以下になる)を全探索します.

G. Divisible Subarrays

$O((N+Q)\log N)$ 時間ですが,TL がきわどかったので微妙方針かもしれません.

まずオンラインクエリ要素を無視して,オフラインに解きます.$2$ 種の分割がありますが片方に固定して考えます.

$r$ を固定したとき,$ans[l]$ を,「$[i,l), [l,r)$ がそういう分割になるような最小の $i$」とします.$r$ をインクリメントしながら $ans[-]$ という列を管理します.

対象となる $l$ は,$a_{l-1}<\min\{a_l,\ldots,a_{r-1}\}$ となるものだけです.よってスライド最小値と同じ理屈で,$ans[]$ に対する更新は全体で $O(N)$ 回で済みます.

$r$ をインクリメントして $ans$ を更新しながら,$[l+1,r)$ でのその区間 min を求めればクエリに答えることができます.

これをオンラインにするには,セグメント木を永続化すればよいです.

定数倍バトル:$2$ 個のセグメント木を作ると $2Q$ 回の区間クエリが必要になりますが,これをまとめることで実装量を犠牲に定数倍高速化….

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