矩陣加速遞推
關於矩陣加速數列遞推:
給定一個遞推數列 \(f[i] = a_1*f[i-1] + a_2*f[i-2] … a_k*f[i-k]\) ,我們普通計算的話肯定是逐個計算,複雜度較大。
我們可以用矩陣表示:
\[ \left[ \begin{matrix} f[i] \\ f[i-1] \\ … \\ f[i-k] \end{matrix} \right] \]
為了遞推出 \(f[n]\) ,我們需要找到一個係數矩陣 \(A\) 使得:
\[ \left[ \begin{matrix} f[i] \\ f[i-1] \\ … \\ f[i-k] \end{matrix} \right] = A\times \left[ \begin{matrix} f[i-1] \\ f[i-2] \\ … \\ f[i-k-1] \end{matrix} \right] \]
就可以這樣計算:
\[ \left[ \begin{matrix} f[n+k] \\ f[n+k-1] \\ … \\ f[n] \end{matrix} \right] = A^{n-1}\times \left[ \begin{matrix} f[k] \\ f[k-1] \\ … \\ f[1] \end{matrix} \right] \]
通過矩陣快速冪來計算 \(A^n\) 可以減小複雜度,問題是如何找到一個 \(A\) 矩陣
容易發現,\(A\)矩陣可以這樣構造:
\[ \left[ \begin{matrix} a_1 & a_2 & … & a_k-1 & a_k \\ 1 & 0 & … & 0 & 0 \\ 0 & 1 & … & 0 & 0 \\ … & … & … & … & … \\ 0 & 0 & … & 1 & 0 \end{matrix} \right] \]
即第一行為係數,從 \(A_{2,1}\) 開始的一條斜線為 \(1\), 其餘為 \(0\),這樣構造可以保證 \(f[i]\) 被計算出來了,而其餘的元素都繼承了上一個矩陣的值。
至此,我們可以愉快地用矩陣加速遞推數列了。