A. Three Decks
目標値は総和の $1/3$ で決まります.
B. Move to the End
末尾 $k-1$ 個は確定で使われて,それ以外に何かひとつです.
C. Card Game
最初のゲームで勝てない側は状況が改善できる余地がなくてそのまま負けです.
D. Array and GCD
操作で作れるのは,総和が初期状態以下であるものならなんでもです.
素数を昇順に並べるのが最適です.素数を十分量列挙しておき,累積和テーブルを構築しておけば,あとは個数を決めると判定できます.
E. Unpleasant Strings
部分列になっているかの判定は貪欲にとっていくことで,答を最大化するには全文字分計算をすすめたあと「貪欲にとっていった場合になるべく後ろの文字を使う必要が出てくるもの」を追加することになります.
クエリに共通の前計算で高速化します.場所・文字に対して次の出現を検索できるようにして,あとは,全文字分計算を進めたときの位置ごとに答を計算しておきます.
F. Numbers and Strings
候補となる $n$ を減らします.例えば $5432199$ と $2345199$ では,$S$ が同じです.足し算・繰り上がりの影響を受ける範囲より左側は並べ替えて最小化されているものだけを考えればよいです.単純に単調増加を仮定してしまうと leading zeros の問題があることに注意.
これで候補が十分小さくなるので,そのうち新しい $S$ を作るもののリストを作っておきます.マルチテストケース要素は,単に毎回二分探索で数えるだけです.
G. Modulo 3
あまりやったことがない実装なので別方針を考えに行ってしまった.結局 mod が $3$ であることを使わずに解きました.
作れる色の列としては,単に「サイクル上では定数」という制約があるだけで,その制約が成り立っているならば葉側から操作していけば作ることができます.よって,問題は「functional graph に更新が来る,(サイクル長 – 1) の sum を答えよ.」となります.
link cut tree でできます.functional graph に対して適当なサイクル上の点を選び,そこから出る辺を消去しておくと,各成分は有向木(辺は根に向かう)になるのでこれを link cut tree で管理します.
出る辺を変更するときは,削除,追加に分けて考えます.削除するときは,
- 根から出る辺 $ab$ の削除: $a,b$ の距離を調べて sum を更新,LCT には何もしない.
- 木上にある辺 $ab$ の削除:根 $x$ の functional graph での行き先を $y$ とする.$xa,ya,xy$ の距離を見ることで $a$ がサイクル上にあるかが分かる.
- サイクル上にあるならば $x,y$ の距離を見て sum を更新.$a,b$ を cut して $a$ を evert.$x,y$ を link.
- そうでないならば,単に cut したあと $a$ を evert.その他の辺の削除:cut したあと始点を evert しておく.
$ab$ を追加するときは $a$ は LCT の根になっています.
- $b$ が同じ成分にあるなら距離を見ることで sum を更新.
- $b$ が違う成分にあるなら link.
とすればよいです.