Processing math: 20%

目次

東京海上日動プログラミングコンテスト2023(AtCoder Beginner Contest 304)G,Ex問題メモ

東京海上日動プログラミングコンテスト2023(AtCoder Beginner Contest 304)

ジャッジが詰まってUnrated。サーバーがんばれー。

G - Max of Medians

G - Max of Medians

問題

解法

中央値として達成できる最大値、みたいな問題は、答えを二分探索して、 「k 以上の値を半数(N+12)以上にできるか?」 の判定問題に落とし込む解法がよくある。

上の桁からの再帰

「XORが k 以上になるペアを最大何個作れるか?」を解く。

2進数で上の桁から再帰的に「k 以上にするためのペア」で分類していく。

Ai のうち、2進数で d 桁目が0のやつの多重集合を Sd0、1のやつを Sd1 とする。
Sd0,Sd1 から1つずつ取ったペア((0,1)ペア)のXORは d 桁目が1、 同じ中から2つ取ったペア((0,0),(1,1)ペア)は0になる。

この時、上の桁から貪欲に、その桁が'1'となるペアを最大化していってよい。(理由は後述)

  d
A 1011  Sd1    Sd0とSd1を優先的にペアにし、
  1001______    (今回はSd0の方が多いので)
  0111  Sd0    残ったSd0同士でペアにする
  0101
  0100
  0010
  0000
  0000

k 以上のペアを数えるには、

なので、徐々に「これとこれの中から1個ずつ取らないといけない」 「この中同士でペアにしないといけない」制約が細分化されていく。

上から x 桁を処理した後の制約内のペアは、どのように組み合わせてもXORの結果の上から x 桁が全て同じになる。
また、k 以上・未満が確定したものは探索の必要は無いので、実質的に調べる中では、上から x 桁は k とも同じになる。

2桁目以降

2桁目以降は、既に2つに分けられ「AB から1つずつ選んでね」という制約付きで上から降ってくることがある。

A,B それぞれで、着目中の桁 d の0,1で4グループに分けて、A_0,A_1,B_0,B_1 とする。

とすればよい。

再帰関数

の2つの関数を定義しておくと、上記の遷移を実現できる。

f(入力として与えられるA, 二分探索で試行するk, 29) が求めるもの。

再帰の末端は、

貪欲でよい証明

(0,1)ペアは優先的に作ってよいとしたが、本当か?

                (0,1)最大      その他の組み合わせ方例
Sd1 1???? x2  →  1???? (0,1)     0???? (1,1)
Sd0 0???? x6      1???? (0,1)     0???? (0,0)
                  0???? (0,0)     0???? (0,0)
                  0???? (0,0)     0???? (0,0)
                                  ↑k以上がこっちの方が多くなることはある?

ない。

ので、(0,1)ペアは優先的に組み合わせることにして問題ない。

計算量

1回の判定問題で、1要素当たり最大 O(\log{A_{max}}) 回の再帰で評価されるので、O(N\log{A_{max}})

二分探索するので、O(N(\log{A_{max}})^2)

Python3

Ex - Constrained Topological Sort

Ex - Constrained Topological Sort

問題

解法

トポロジカルソートと、区間スケジューリング問題みたいな R_i の昇順に貪欲的に決めていけるやつ(呼び方忘れた)の複合。

問題は以下のように言い換えられる。

トポロジカルソートのアルゴリズムは、ソート結果を記録する空配列 T を用意し、流入辺が無くなった頂点からキューに入れ、キューから取り出された順に T に追加しグラフから削除する、というものである。

キューに複数の頂点が同時にあるとき、どれを取り出すかに自由度がある。

という改変を加えることで、条件を満たすソート結果の一例を作れる。(または破綻する)

キューから取り出す優先順位である「制約が厳しい」とは、 その頂点の R_i だけでなく、そこから辺で繋がる頂点の R_i にも影響される。

    ①→②   この時、①は 4 番目までに置く必要がある
Ri  10   5

よって、まず最初に後ろからトポロジカルソート的なことをし、各頂点の実質的な制約 R'_i を求めておく。

あとは、先ほどの改変を加えてトポロジカルソートし、N 個の頂点を矛盾無く並べられるかチェックすればよい。

Python3