Xmas Contest 2018 E: Exclusive☆OR 解説
https://atcoder.jp/contests/xmascon18/tasks/xmascon18_e
問題概要
個のブール変数から
個とった XOR たちを,AND と OR と NOT を使って作る.NOT の使用回数を最小化せよ.
N = 1 のとき
何もしなければ正解です.
N = 2 のとき
なので,
に NOT を使うと
回でできます.NOT なしでは
と
しか作れないので,
回ではできません.
N = 3 のとき
NOT 回でできます.下からの評価 (
回ではできない) は後ほど.
の場合はこちらで手で遊べる.
と書いてあるやつで遊んでみると解けるかもしれません.正解できる NOT 対象はいくつかあるのですが,次の方法が一般の での解法に繋がります:
は「
のうち true のものの個数が
のいずれかである」かどうかを表すブール変数になっています.この変数に着目することが以下の解法での鍵となってきます.
N - 1 回解法
次の ステップでできます:
を求める.これは AND と OR だけでできる.
を求める.
である.ここで
回の NOT を使っている.
を求める.まず,
を「
と
以外のうち true が
個以上」かどうかとする.これは AND と OR だけで求まる.すると,以下が成り立つ:
最後の式が何を意味しているかというと,「 と
のうちには true が
個以上」かつ「
と
以外には true が
個以上」かつ「全体では true がちょうど
個」,というのを
について OR をとっていますが,
なので「以上」が消えて,「
と
のうちには true がちょうど
個」,すなわち
がもれなく求められている,ということになります.
log N 回解法
上の解法のステップ は実は
回の NOT でできてしまいます.
のときの例を示すとこんな感じ:
一般には, に対して,「下から
ビット目が
である数に
を足したもの」たちが
の中身に入るような変数に NOT をすると上手くいきます.すごい.
行数制限
ここまで NOT の回数だけを気にしていましたが,この問題では AND, OR, NOT を合わせて 回以下でなければいけないのでした.ステップ
とステップ
で「true が
個以上」みたいなのを求めるのを愚直にやると
について指数回かかってしまいます (
くらいまで正解できて,
点です).これは,DP で
の計算でできます:
for i = 0 to N - 1: for x = N - 1 to 1: f(x + 1, ..., N) := f(x + 1, ..., N) OR (f(x, ..., N) AND b_i) f(1, ..., N) := f(1, ..., N) OR b_i
ステップ のほうでは
回 (
たちから
個除いて) これをやるので
回の計算になります.実はこれを
にすることもできますが省略します (満点には必要ないです).これで無事に
行に収まるようにできました.
下からの評価
NOT の最小使用回数は です.これ未満ではできないことを示しておきます.
NOT の使用回数が でできるプログラム
が存在したとします.
の入力に
の
通りを入れたとき,
なので鳩ノ巣原理より,どれか
パターンでは
回の NOT の計算結果が全部一致するはずなのです.それを
と
(
) のときとします.
このとき,以下のようなプログラム が作れてしまいます:
の入力は
変数である.入力
に対して,
に入力
を与える.
の計算途中において,
箇所のNOT を使う部分は,上で計算結果が一致したという値の定数に置き換える.
の出力
をとってきて
の出力とする.
すると の出力は
ですが,
は AND と OR しか使っていないので NOT ができてしまうのは矛盾です.
コメント
コンテスト開始後はしばらくジャッジが正常に動いておらず申し訳ありませんでした.
満点までの道のりが壮大な感じで,難しい問題だったと思います.でもなんかすごいですよねこれ.
作題のきっかけは,「3-not problem」 (2 NOTs problem だったり呼称は安定していないっぽい) という一部界隈では有名らしい問題を知ったことです. で,
を NOT 2 回で作ろうというもの.一般の
では最小
回です.
たちがあれば XOR は作れるのですが,
を考えたらもう少しうまくできるのではと思い,
を全探索していろいろ気づいた,という流れでありました.