かしのブログ

競技プログラミングとか

第二回全国統一プログラミング王決定戦予選 C - Swaps

問題

 A_1, \cdots, A_N  B_1, \cdots, B_Nがある。以下の操作を N-2回以下行って、 A_i \leq B_iにできるか判定する。

  •  1 \leq i, j \leq Nを選択し、 A_i A_jの値を入れ替える

atcoder.jp

考察

 Bが昇順であると仮定する。 Aを昇順にソートして比較するとき、 A_i \leq B_iを満たさない iが存在すれば、実現不可能である。以下、これは満たされていると仮定する。

 Aをソートするのに N-2回以下ならば実現可能である。以下では、 Aのソートに N-1回かかった場合について考える。

次の補題を利用する(証明は後述)

 N-順列 Pを選択ソートで昇順に並び替えるときに必要な交換回数が N-1回なら、 Pの任意の2要素を交換した順列 P^\prime N-2回の交換で昇順にできる

 A, Bともに昇順になっているので、 A_j A_{j+1}を交換して A_i \leq B_iが成り立つ j、すなわち A_{j+1} \leq B_jになるような jが存在するか判定すればいい。

証明

[補題]  N-順列 Pを選択ソートで昇順に並び替えるときに必要な交換回数が N-1回なら、 Pの任意の2要素を交換した順列 P^\prime N-2回の交換で昇順にできる

 Pは、昇順に並んだ N-順列 E (= [1, 2, \cdots, N]) Eの任意の要素 p_0から、次の操作を N-1回行って作ることができる。

  • 今まで交換していない番号 p_i p_0を交換する。

 Pの交換すうr2要素 x, yのうち、 x = p_0としても、 Pを作るために選んだ番号の列 [p_1, p_2, \cdots, p_{N-1}]が存在し、 y = p_kなる k(1\leq k \leq N-1)が存在する。  P^\primeは、 x p_kから、 Pを作ったときと逆順に操作を行えば、 k回の操作で p_0\sim p_k k+1要素を昇順に戻すことができた。 残りの N-k-1要素は、 N-k-2回の交換で任意の順番に並び替えられるので、 N-k-2回以下で全体を昇順に戻すことができた。 よって、 P^\prime全体は N-2回以下の交換で昇順にできる。

 P^\prime N-2回より少ない交換で昇順にできるなら、 P N-1回未満の交換で昇順にできるが、これは仮定に矛盾するので、 P^\prime N-2回の交換で昇順にできることが示せた。

実装

atcoder.jp