Codeforces Round 1114

ブログにも解説を載せるのは,2026/08 中くらいにします.ちょっと管理や,自分のための検索資産としていまいちなので.

カテゴリページ → https://maspypy.com/category/codeforces

のお知らせも見てください.


A. Riptide

そのままシミュレーション.

B. Evanescent

初期スコアからの差分を考えます.

影響するのは長さ 1 の成分だけです.これがあれば $-1$,さらに両側の文字が一致するなら $-2$ になります.

C2. Marenol (hard version)

同じ parity のところだけを見ると,単に隣接スワップができるということになっています.

D. Silhouette

最小値が $0$ であることが必要.

値ごとにグループ分けします.あるグループと次のグループの値や個数を見ると,そのグループの $a$ での値が決まります.

あとは,増加していることや正であることなどをチェックします.

E. Chronostasis

総和が $0$ 以下だと,不可能です. $a_n$ は総和に等しいので.

そうでないとき,可能です.

なぜならば正のものを足していってから負のものを引いていくことで,途中は常に $a_1$ 以上または $a_n$ 以上にできるからです.

必要条件のもと,各時点で正であれば最後まで作る方法が存在することが同じように示せるので,辞書順最小化は各時点で正になるような最小の選択肢を選んでいくだけで良いです.

F. Whiplash

しばらく単一の $j$ で操作してしまった.

$n=4$ あたりで手計算すると,作れる状態が $(n+1)\times n!$ 通りであることが分かります.

  • 初期:[a,b,c,d]
  • [a,ab,ac,ad]
  • [ab,b,bc,bd]
  • [ac,bc,c,cd]
  • [ad,bd,cd,cd]
  • これの並べ替えもできる.

これをどのように思うかですが,変な言い換えがあって,

  • 初期状態を [0,a,b,c,d] と思う.
  • どれかが $0$ になるように xor する.
  • $0$ でない要素を自由な順に並べたものが作れる.

といえます.どれを $0$ になるようにするかですが,これは $A,B$ の総 XOR から決められます.

G. Nightcrawler

葉の個数を $K$ とします.まず, $k\geq K$ について, $ANS[k]$ は次のように定式化できます.

  • 葉 $K$ 個と,ワイルドカード $k-K$ 個を用意します.これらを左側頂点とします.
  • 木の $N$ 個の頂点を用意します.これらを右側頂点とします.
  • 左側を飽和するような最大重みマッチングを求めてください.

このとき,次が成り立ちます.

  • $k=K$ の場合の解をまず求める.
  • $k=K+1,K+2,\ldots$ の解は,ワイルドカード頂点を追加するたびに右側の最大重み頂点を使うことで得られる.

実は成り立たないと勘違いして(反例を発見したつもりになって)かなりの時間悩んでしまったので,反省して,証明を確認します.

次の形で考えます:

二部グラフがある. $v_i$ は左側頂点とする.

  • $X$: $v_0,v_1,\ldots,v_{n-1}$ を飽和するサイズ $n$ マッチング
  • $Y$: $v_0,v_1,\ldots,v_{n-1},v_n$ を飽和するサイズ $n+1$ マッチング

適当なタイブレイクにより最大重みマッチングは一意だと考える.このとき, $Y$ の右側端点集合は $X$ の右側端点集合に $1$ 点追加したものである.

逐次最短路による証明

source から $v_i$ に $i\times INF$ の辺重みがあると思って最小費用流を求めることを考えればよい.

直接的な証明

$X,Y$ の xor を考えると例によって交互パスと交互サイクルに分割される. $v_0,\ldots,v_{n-1}$ の次数は $2$, $v_n$ の次数が $1$ であることなどから,

  • $v_n$ を端点とする交互パスがひとつあって,これは右側頂点で終わる.
  • 右側から右側への交互パスがあるかもしれないが,サイズ $n$ 時点での最大性と一意性の仮定からこれはない.
  • 交互サイクルも同様.

というわけで, $Y$ は $X$ をひとつの交互パスで augument した形に限定される.

このときマッチングは組み変わるが,右側端点集合はひとつ追加されるだけ.


というわけで,元の問題に戻ります.追加頂点はワイルドカードなので,サイズ $K$ マッチングからの追加は自明な貪欲です.よってサイズ $K$ マッチングを求めることが課題です.

最大重みマッチングですが,これは頂点重み版です.マッチングの端点集合にできるような右側頂点集合はマトロイド(横断マトロイド)なので,貪欲に $1$ 点ずつ足しながら,最大マッチングの存在判定をしていきます.あるいはこれも,逐次最短路で一度選んだ点が削除されないことから考えてもよいです.

最大マッチングの判定は,Hall の定理を使えます.結局,次の形になります.

  • 重み最大の頂点から,採用できるならば採用する.
  • 採用できるのは,任意の木の頂点 $v$ について次が成り立つ場合:subtree 内で採用した頂点数が,subtree 内の葉の個数を超えない.

あとは簡単で,頂点 $v$ における残り許容量を考えると,パス加算とパス min のパスクエリで処理できます.

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