解説:貢物
技術室奥プログラミングコンテスト#2 問題G
問題概要
ある品物をささげるか否かを真偽値変数としたとき
に𝑎 ∧ bの形の論理式がいっぱい与えられえる
それらをandで結合しながらまとめていく
まとめるそれぞれの段階で、正しい真偽値割り当て
が存在するか判定せよ
考察
𝑎 ∧ 𝑏は、 𝑎 ∨ 𝑏と表せる。
これをandでつなぐのだから、これは2SAT
2SATは線形時間で解ける(これはここでは解説しませ
ん)
考察
しかし、毎回2SATを解いていては、最悪O(M^2)に
なる。
部分点15点
満点のためにもっと考察が必要
考察
合併の様子を、以下の図の木のように表してみる
3,4,2,6,1,7,5
3,4,2 6,1,7,5
3,4 2
3 4
6,1,7 5
6 1,7
1 7
ここで、1番上のノードで、左から何番目までの村
の掟なら守れるか、を二分探索で調べる。
考察
3,4,2,6,1,7,5
3,4,2 6,1,7,5
3,4 2
3 4
6,1,7 5
6 1,7
1 7
たとえば、3,4,2,6,1で可能だったとすると、
赤く塗られた部分は計算しなくても、掟を守ること
ができるとわかる。
考察
3,4,2,6,1,7,5
3,4,2 6,1,7,5
3,4 2
3 4
6,1,7 5
6 1,7
1 7
考察
では、次のような場合において、赤い部分だけが可
能であるとわかった場合は?
・
・
・
・
・
・
・
・
・
・
・
・
考察
では、次のような場合において、赤い部分だけが可
能であるとわかった場合は?
→青いバツ印のついた部分が不可能とわかる。
・
・
・
・
・
・
・
・
・
・
・
・
考察
結局、どのような結果でも、左の方にだけ下って
行った場所にあるノードの判定がまとめて行える。
つまり、全体で処理すべき場所は、一番上と、右の
子になっているノードだけ。
考察
先ほどの木を作る際に、右の子の大きさが左の子の
大きさを超えないようにしておくと、データ構造を
マージする一般的テクみたいな感じで、処理する
ノードの大きさの合計が、O(MlogM)になる。
それぞれで二分探索するから、全体でO(Mlog^2M)
おしまい

解説:貢物