ARC228 A - Row and Col swap

行と列の交換

考え方

同じ値 $i$ が $2$ つずつあると考えにくいので、まずはここを工夫する。

ある操作で、最終的に条件が満たされたとする。
このとき、$P$ 側にある $i$ を $+i$、$Q$ 側にある $i$ を $-i$ と書き換える。
そして操作を逆再生すると、与えられた $2$ つの順列に適切に符号がつけてあったことにできる。

このとき、異なる割り当てが同じ手順で両方条件を満たすようにはならない。
したがって、問題は以下のように言い換えられる。

PとQの同じ値の、片方は+、片方は-に置き換える。
問題にある操作をM回繰り返して、P側を全て+、Q側を全て-にする。
このような初期符号の割り当て方と手順は何通りあるか?

ということで、初期符号と手順の組 $2^N\times (N^2)^M$ 通り全ての検証をすればよい。
これは、前後半分けて動的計画法を $2$ つ行うことで達成できる。

DPテーブルは、同じ縦列の符号の組がいくつあるかごとに情報を持つ。
$[+-]$ という組が $i$ 組、$[-+]$ という組が $j$ 組あるとする。
$[++]$ と $[--]$ は同数あるので、残りの半分ずつある。
このような組数になっているパターン数を dp[i][j] とする。

前半の動的計画法

初期の符号割り当て $2^N$ 通りの分類を求める。

まず、$P$ と $Q$ を巡回順に並べなおす。
というのは、与えられた問題で $P_i$ と $P_j$ を、$Q_i$ と $Q_j$ を同時に入れ替えても影響がない。
よって、例えば以下のように、巡回順に並べなおす。

P : 1 2 3 4 5 6
Q : 5 6 2 4 1 3
↓
P : 1 5 2 6 3 4
Q : 5 1 6 3 2 4

すなわち、$(1,5),(2,6,3),(4)$ がそれぞれの中で $1$ つずつ右にずれる巡回になっているような状態にする。
そしてこの順番通りにDPを行うことで、持つ状態数を減らすことができる。

dp[i][j] は前述の通りの意味で、さらに次が $[+?]$ であるべきか $[-?]$ であるべきかで分けて数える。
巡回が続いている限り、$1$ つ前が $[?+]$ であれば次は $[-?]$ である必要がある、というのを利用する。

つまり、巡回の内部では、配るDPとして以下の $4$ つの遷移が成立する。

巡回の切れ目では、以下のように考える。

切れ目では、次に何が来るべきという指定がないので、全て「次が $[+?]$ であるべき」側で数えておく。
すると、自然と次の巡回が $[+?]$ で始まったものだけ数えることになる。
そして、巡回の最後の組では $4$ つのうち $[?-]$ に相当する $2$ つの遷移だけ行う。
結果として、設計通り dp[i][j][+] の方だけ値が構築され、dp[i][j][-] はすべて $0$ になる。

このとき、dp[i][j][+] に入っている個数は、最後の巡回が $[+?]$ で始まり $[?-]$ で終わるものだけ。
これに、最後の巡回が $[-?]$ で始まり $[?+]$ で終わるものの個数を加えなければならない。
実はこの個数は、全体の $+/-$ を入れ替えることを考えると、実は dp[j][i][+] に入っている。
よって、$i$ と $j$ を入れ替えた値同士、お互いをお互いに足せばよい。
(dp[i][i][+] は $2$ 倍することになる)

巡回順に並べなおしたのを見ながら $N$ 要素分繰り返す。
これで、初期の符号割り当て $2^N$ 通りの分類を求めることができた。

以後 [-] のデータは不要なので、[+] の方だけ取り出したものにDPテーブルを作り直す。

後半の動的計画法

後半では、このデータが操作 $1$ 回ごとにどう変わるか調べればよい。
操作する場所の選び方は $N(N-1)/2\times 2+N=N^2$ とおりある。
そのときの $i$ や $j$ の変化、つまり遷移先は以下のようになっている。

$[++]$ と $[--]$ はそれぞれ $k=(N-i-j)/2$ 組ある。

この遷移を愚直に $M$ 回実行すればよい。

最終的に、$N$ 組全てが $[+-]$ になっている個数が答えとなる。

計算量

計算量は、前半が $O(N^3)$、後半が $O(MN^2)$ である。
メモリも計算量も余裕がないので、明らかにデータがない場所の処理をスキップするなど工夫すること。
C++ならそこまでせずとも一応通りそうではあるが。

入力例1での動作

入力を受け取る。

n: 3
m: 1
p: {1, 2, 3}
q: {1, 3, 2}

まず、各位置にある $P$ 側の値から $Q$ 側の値への対応を見ると、$1\to1,2\to3,3\to2$ となる。
したがって、巡回は $(1),(2,3)$ の $2$ 個である。

前半のDPを行う。
最初の巡回 $(1)$ を処理し終えると、値 $1$ の符号の付け方は $[+-]$ と $[-+]$ の $2$ 通りである。
DPは次のようになる。

dp[1][0][+] = 1
dp[0][1][+] = 1

次に巡回 $(2,3)$ を処理する。
最初の $2$ を処理した時点で、DPは次のようになる。

dp[1][0][-] = 1
dp[2][0][+] = 1
dp[0][1][-] = 1
dp[1][1][+] = 1

最後の $3$ を処理して巡回を閉じ、さらに $+/-$ を全て反転した場合も加える。
前半DPの最終状態は次のようになる。

dp[3][0] = 1
dp[2][1] = 1
dp[1][2] = 1
dp[0][3] = 1
dp[1][0] = 2
dp[0][1] = 2

合計は $1+1+1+1+2+2=8=2^3$ で、全ての初期符号割り当てが分類されている。

後半では、この状態から操作を $M=1$ 回行う。
$N=3$ なので、各状態から選べる操作は $N^2=9$ 通りである。
遷移後のDPは次のようになる。

dp[3][0] = 7
dp[2][1] = 11
dp[1][2] = 11
dp[0][3] = 7
dp[1][0] = 18
dp[0][1] = 18

合計は $72=8\times9$ で、$8$ 通りの初期符号割り当てそれぞれについて $9$ 通りの操作を全て数えられている。

最終的に $P$ 側を全て $+$、$Q$ 側を全て $-$ にするには、全 $3$ 組が $[+-]$ であればよい。
よって答えは dp[3][0] の値である $7$ となる。

注意点

答えは $998244353$ で割った余りを要求されているので、剰余類環の考えに従って処理する。
何か足し算や掛け算をするたびに結果を % 998244353 する。
計算量削減のために剰余を取る回数を減らしてもいいが、long long 型から溢れない程度にすること。

別解

特になし。