Processing math: 20%

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

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

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

G - Max of Medians

問題

  • 2N 個の非負整数 A1,...,A2N がある
  • 2個ずつ組み合わせてbitwise-XORし、N 個の非負整数を作ることを考える
  • 中央値として考えられる最大値を求めよ
    • 中央値: 昇順に並べて N2+1 番目の要素
  • 1N105
  • 0Ai<230

解法

中央値として達成できる最大値、みたいな問題は、答えを二分探索して、 「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 以上のペアを数えるには、

  • kd 桁目が '1'
    • 次の桁からは、Sd0Sd1 から1つずつ選んでペアにすることが必須
    • その前提のもとで、k 以上のペアを最大化
  • kd 桁目が '0'
    • min 個のペアは k 以上確定
    • 残り(S_{d0},S_{d1} のうち要素数が多い方)の中で、次の桁以降で k 以上となるペアを最大化
    • ただし、あくまで(0,1)ペアを取った残りを組み合わせる前提なので、上限は \frac{要素数の差分}{2} 以下

なので、徐々に「これとこれの中から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 とする。

  • kd 桁目が '1'
    • (A_0,B_1) または (A_1,B_0) でペアにしないといけない。それぞれで最大化した結果を求めて合計
  • kd 桁目が '0'
    • (A_0,B_1) および (A_1,B_0) で優先的にペアを作る
    • A_0,B_0 がともに余るとき、この2つから1つずつ選んで k 以上を最大化
    • A_1,B_1 がともに余るとき、この2つから1つずつ選んで k 以上を最大化
      • ※ただし上限は余る個数

とすればよい。

再帰関数
  • f(A, k, d)=A から2個ずつ取って k 以上のペアを最大化した時の個数、d 桁目に着目
  • g(A, B, k, d)=A,B から1個ずつ取って k 以上のペアを最大化した時の個数、d 桁目に着目

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

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

再帰の末端は、

  • 最後の桁まで行き着いたら(d=-1
    • f(A,k,d) なら \left \lfloor \dfrac{|A|}{2} \right \rfloor
    • g(A,B,k,d) なら \min(|A|,|B|)
  • 途中で打ち切れる条件
    • f(A,k,d)なら |A| \lt 2 のとき、結果は0
    • g(A,B,k,d) なら \min(|A|,|B|)=0 のとき、結果は0
貪欲でよい証明

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

  • 敢えて(0,1)ペアを最大まで作らず、(0,0)、(1,1)のペアを多くすることで、k 以上にできる個数が多くなることはあるか?
                (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以上がこっちの方が多くなることはある?

ない。

  • kd 桁目が'1'のとき
    • (0,1)ペアを多くしてXORも'1'にしないと k 未満確定なので、(0,0)(1,1)を増やす意味は無い
  • kd 桁目が'0'のとき
    • (0,0)ペア、(1,1)ペアいずれかの中に k 以上にできないものがあるなら、それをバラして(0,1)として組み合わせた方がよい
      • (0,0):x,(1,1):o → (0,1):o,(0,1):o
    • 全て k 以上にできるとしても、(0,1)として組み合わせても損しない

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

計算量

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

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

Python3

Ex - Constrained Topological Sort

問題

  • N 頂点 M 辺の有向グラフがある
  • (1,2,...,N) の順列 P=(P_1,...,P_N) として、頂点 i に値 P_i を割り当てる
  • P は以下の条件を全て満たさないといけない
    • u→v に辺があるとき、P_u \lt P_v
    • 各頂点に割り当て可能な値の範囲制約があり、頂点 i に対して L_i \le P_i \le R_i を満たす
  • 割り当て可能か判定し、可能なら P の一例を示せ
  • 2 \le N \le 2 \times 10^5
  • 0 \le M \le 4 \times 10^5

解法

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

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

  • グラフの辺に従ってトポロジカルソートし、頂点番号を順に記録する
  • 頂点 i は、ソート結果で L_i~R_i 番目の中にないといけない
  • 矛盾無くソートできたなら、a 番目に頂点 b が記録されたとして P_b=a としたものが答え

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

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

  • キューに入っている頂点の内、制約が厳しいものを優先的に取り出す
  • 頂点 i が取り出されたとき、L_i~R_i 番目の中にあるかチェックする
  • まだ T の長さが L_i-1 に達していないなら、頂点 i は(流入辺が無くても)キューには入れない
    • キューに入っている頂点は、L_i の条件は必ず満たす状態にしておく
    • 入れられない頂点は、「T の長さが l になったら入れる」みたいなのに別途記録して後で入れる

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

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

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

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

  • R'_i = \min(R_i, R'_{j1}-1, R'_{j2}-1, ...)
    • ただし i から直接辺で繋がる頂点を j_1,j_2,... とする

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

Python3

programming_algorithm/contest_history/atcoder/2023/0603_abc304.txt · 最終更新: 2023/06/05 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0