部屋の集合 S = {0, 1, …, N-1} とし,部屋 i からの右耳での行き先を f(i), 左耳での行き先を g(i) とする.
f, g は S -> S の関数である.
条件は f^Z・g・f^Y・g・f^X = id である.よって g は全単射で,X + Y + Z > 0 であれば f も全単射である.
(X + Y + Z = 0 の場合は以下の議論は使えないが,f が全単射に限らないことを除いて結果が一致する)
全単射であるから,逆写像を自由にぶつけることができて便利である.
すると,適当な置き換えにより結局 S -> S の全単射 f, g で,f^2 = g^|X+Z-Y| なるものの数を数えればいいことになる.
f^2 = g^|X+Z-Y| = h とおく.h を固定したときの f, g の数を数える気分で答えを求める.
S -> S の全単射は,一般に「サイクル」(f(0) = 1, f(1) = 2, f(2) = 0 のように,関数適用で循環するときの循環節) に分解できる.
関数の繰り返し適用により,サイクルがどう分解するかを調べると,長さ l のサイクルは k 回適用のあとで,長さ l/gcd(l, k) のサイクル gcd(l, k) 個に分解することがわかる.
あとは,長さ l のサイクルがちょうど m 個与えられたとき,繰り返し適用の後でそれらに分解するような「サイクルたち」が何個あるか数える (DP).
この DP テーブルがあれば,h について (残りの要素, 次に割り当てるサイクル長) をキーに DP を行うことで解ける.
2234 (Usagitobi)
{(ax+cy mod m, bx+dy mod n) | x, y ∈ Z} の元の個数を求めるとよい.