Codeforces Round 647 – Thanks, Algo Muse!

スポンサーリンク

A. Johnny and Contribution

$A$ について昇順に選んだときに上手くいっているかどうかチェック.

B. Johnny and Grandmaster

大きい方から貪欲シミュレーション.まず片方に $p^X$ を選びます.残りは総和が $p^X$ になるまでは貪欲に逆側に入れていってよいです.総和が等しくなったらそれらをキャンセルして続きからやります.

C. Johnny and Megan’s Necklace

目標値を決めると,$[0,2^k)$ を頂点集合として各鎖を無向辺として eulerian circuit ということになります.

D. Johnny and James

木があって $K$ 頂点残して,頂点間距離の sum を最大化という問題になっています.残す頂点の重心を考えると,そこから遠ざけることが可能な頂点は遠ざけた方が得になって,特に削除頂点集合は連結であることが示せます.

各方向のパターンとして,中心に近い部分・遠い部分からそれぞれいくつかを残すというパターンに限定できます.また近い部分を残すのは遠い部分から $K/2$ 個程度の頂点を残すパターンのみです.

これで各方向についてのパターン数が線形になります.また各方向について頂点数を決めるとその方向にある辺の寄与の和が求まるため,最終的なコストも方向ごとに計算しておけます.

方向ごとの凸性もいえるので,あとは各方向について個数が $0$ 個の状態からはじめて,$1$ 個追加するときのコストが大きいものからとっていくだけです.

E. James and the Chase

まず $r$ が good であるかの判定を考えます.$r$ を根とする有向木をひとつとります(これがとれなければ明らかに good ではない).$r$ を始点として有向木に含まれない辺を使うパスがあるとダメです.したがって,条件は有向木に含まれない辺がすべて後退辺であることとなります.

20% が条件を満たすとすると,乱択で判定を行えばそのうちひとつを見つけることは可能です.

ひとつ $r$ を見つけてその有向木をとります.この状態で $v$ が good であるか否かを判定します.

必要性として $r$ へのパスが存在する必要があります.したがって,「ある subtree 内の辺を使って先祖に行く」ことの繰り返しで $r$ へ行ける必要があります.

また各段階で,subtree から出るために使える辺は唯一でなくてはいけません.これは $v$ から親へのパスが一意になるようにするためです.

したがって,頂点列 $v_1=v, v_2, \ldots, v_k=r$ であって,$v_i$ の subtree 内には $v_i$ の先祖への辺が唯一存在し,その行き先が $v_{i+1}$ であるものの存在が必要です.この条件下で $v$ が good であることも簡単に確認できます.

この条件によって根側から順に各頂点が good であるか否かを確定させていくことができます.

F. Johnny and New Toy

読解を頑張ると,$W$ について cartesian tree を作って,各頂点で左右の部分木のスワップができるということになります.したがって,各頂点で左側集合と右側集合を好きな順に並べて集合間の転倒数を最小化するという問題になります.

cartesian tree の深さは $O(\log N)$ と考えてよいです.$W$ がランダムとのことなので,treap の深さの解析と同じです.よって点変更が来たときに,$O(\log N)$ 頂点について何らかの再計算を行えばよいです.

何らかの再計算というのも簡単で,左右の集合を適切にもって,点と集合の間の転倒を計算するだけです.

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