K - 乱数調整 Editorial by maspy


問題文中の数式が壊れています。正しい数式は

  • \(a_0 = A\)
  • \(a_{t+1} = (a_t/2) \verb|^| (a_t \% 2 \times B)\)

となります。


ついでに公式解説について少し補足しておきます。

\(2^{36}\) 未満の整数全体を、\(\mathbb{F}_2\) 上のベクトル空間と見なせば、\(a_t\) から \(a_{t+1}\) を得る規則は \(\mathbb{F}_2\) 線形写像です。したがって、行列 \(A\) およびベクトル \(v, w\) に対して、\(A^nv = w\) となる \(n\) を求める問題へと帰着されます。 この \(A\) は可逆とは限らないことが厄介です。

そこで、\(2^{K-1}\leqq B < 2^K\) となる \(K\) をとります(\(B=0\) は場合分けで別処理)。すると、

  • \(a_t\) は、\(36\) 項目以降では常に \(2^K\) 未満
  • \(a_{t}\) から \(a_{t+1}\) を定める変換を、\(2^K\) 未満の部分に制限すると、これは可逆。

が成り立ちます。したがって、数列の先頭の方を前処理してしまえば、行列 \(A\) に可逆性が成り立つ場合に帰着できて、あとは \(A^{iH+j}v=w\iff (A^H)^iv = A^{-j}w\) 等の変形から Baby-step giant-step アルゴリズムにより解くことができます。

posted:
last update: