yukicoder No.1087 転倒数の転倒数

yukicoder.me

Writer解とは解法が違うらしい。

問題

$N, K$ が与えられます。

次の条件を満たす $N\times N$ の行列 $S$ が存在するか判定し、存在するなら一つ構築しなさい。

  • $S$ の $i$ 行目の転倒数を $A_i$ とする。
  • $S$ の $i$ 列目の転倒数を $B_i$ とする。
  • $[A_1, ..., A_N]$ の転倒数 $+\ [B_1, ..., B_N]$ の転倒数が $K$ である。

制約

  • $1≦N≦1000$
  • $1≦K≦10^9$

解法

$N(N-1)< K$ のときは明らかに不可能です。逆に、これ以外のときは可能です。

以下では、これを実際に構築します。なお、以降では全て0-indexedになります。

 

突然ですが、$a=\{0, ..., N-1\}$ の順列とし、$S$ を $S_{i, N-1-a_i}=10^6, $ それ以外は $0$ とします。

例えば、$a=[2,1,3,0]$ のときはこんな感じです。

\begin{pmatrix} 0 & 10^6 & 0 & 0 \\ 0 & 0 & 10^6 & 0 \\ 10^6 & 0 & 0 & 0 \\ 0 & 0 & 0 & 10^6 \end{pmatrix}

このとき、$A$ と $B$ は共に $\{0, ..., N-1\}$ の順列になります。

この解法の肝は、このように $S$ を作ると $a$ の転倒数と $A$ の転倒数と $B$ の転倒数が全て等しくなることです。

これは、次のように証明できます。

  • まず、よく考えると $a=A$ なので、$a$ の転倒数と $A$ の転倒数は等しくなります。
  • $A$ の転倒数は、「$S$ 中の $10^6$ のペアであって、片方がもう片方の左上にあるものの個数」と言い換えることができます。
  • $B$ の転倒数も、「$S$ 中の $10^6$ のペアであって、片方がもう片方の左上にあるものの個数」と言い換えることができます。
  • よって、$A$ の転倒数と $B$ の転倒数は等しくなります。

これによって、$K$ が偶数のときは $a$ の転倒数を $K/2$ にすることで条件を満たす $S$ が構築ができます。

以降では、$K$ は奇数とします。

 

まずは、$a$ の転倒数が $(K+1)/2$ になるように $a$ を作ります。このとき、$a$ 内の $0$ の位置が $1$ の位置より右に来るように $a$ を作ります。

( $(K+1)/2≧1$ より、数列 $a$ をそういう風に作ることは可能です。)

今度は、$T_{i,j}=i+j$ となる $N\times N$ 行列 $T$ を考えます。

例えば、$N=4$ のときはこんな感じです。

\begin{pmatrix} 0 & 1 & 2 & 3 \\ 1 & 2 & 3 & 4 \\ 2 & 3 & 4 & 5 \\ 3 & 4 & 5 & 6 \end{pmatrix}

この $T$ は、どの隣接する $2$ 項を交換しても、それに対応する行または列の転倒数のみが $1$ 増える、という特徴があります。

そして、$S_{i,j}=\max(T_{i,j}, $ さっきまでの $S_{i,j})$ とします。

例えば、$a=[2,1,3,0]$ のときはこんな感じです。

\begin{pmatrix} 0 & 10^6 & 2 & 3 \\ 1 & 2 & 10^6 & 4 \\ 10^6 & 3 & 4 & 5 \\ 3 & 4 & 5 & 10^6 \end{pmatrix}

そして、$a_x=0$ となるような $x$ について、$S_{x,1}$ と $S_{x,2}$ をswapします。

\begin{pmatrix} 0 & 10^6 & 2 & 3 \\ 1 & 2 & 10^6 & 4 \\ 10^6 & 3 & 4 & 5 \\ \color{red}{4} & \color{red}{3} & 5 & 10^6 \end{pmatrix}

こうすると、$B$ は変わらずに、$A$ の $0$ だった項が $1$ になります。

すると、変える前には $A$ 内の $0$ の位置は $1$ の位置より右にあったので、$A$ の転倒数は $1$ 減ります。

変える前の $A$ の転倒数 $+\ B$ の転倒数は $(K+1)/2\times 2=K+1$ だったので、変えた後の $A$ の転倒数 $+\ B$ の転倒数は $K$ となり、条件を満たす $S$ が構築できました。

例外

ただし、このアルゴリズムは $K$ が奇数のときに「$S_{x,1}$ と $S_{x,2}$ は共に $10^6$ ではない」という前提条件を必要としています。

この前提条件は $N≦2$ のときに崩れるので、このアルゴリズムは $N=2,K=1$ で落ちます。

このときだけ場合分けしてやりましょう。例えば、

\begin{pmatrix} 3 & 2 \\ 0 & 1 \end{pmatrix}

などです。

提出コード

解説にすると長いけど、頭の中で解法を整理してる時間はもっと短い。むしろ解法を思いつくまでの時間が長すぎる。

余談:この提出を貼って気がついたけど、yukicoderが500000提出に到達したみたい。おめでとう!

yukicoder.me