常系數齊次線性遞推


常系數齊次線性遞推

要干啥

已知

\[f[n]=\sum_{i=1}^k C_if[n-i] \]

\(f[n]\)的值,\(n\le 10^9,k\le 20000\),答案取模。

暴力做法

如果復雜度\(O(nk)\)允許的話,顯然是可以直接\(dp\)轉移的。
\(k\)很小的時候,轉移寫成矩陣形式,假設轉移矩陣為\(M\),可以得到:\(\displaystyle f[n]=f[0]*M^n\),這里的\(f\)是向量的形式。
復雜度為\(O(k^3logn)\)

所以到底要怎么做

顯然我們已知矩乘的時候是一個\(n\)維向量乘上轉移矩陣得到了一個\(n\)維向量。
考慮這個轉移的特征方程:

\[x^k=\sum_{i=1}^k C_ix^{k-i} \]

把它移項之后我們定義為特征多項式\(C(x)\)

\[C(x)=x^k-\sum_{i=1}^k C_ix^{k-i} \]

根據\(Cayley–Hamilton\)定理,得到\(C(M)=0\),即把\(x\)替換為轉移矩陣\(M\),最終的結果是一個零矩陣。
而我們要求的就是\(M^n\),因此,我們只需要知道\(M^n\ mod \ C(M)\)的結果就好了。
求解這個過程可以類似快速冪的倍增求解,復雜度是兩個\(log\)
假設最終求解出來的余數多項式為

\[G(x)=\sum_{i=0}^{k-1}g_ix^i \]

假設我們中間的向量為\(A[i]\),那么最終我們的答案向量可以寫成:

\[\begin{aligned} A[0]G(M)&=A[0]\sum_{i=0}^{k-1}g_iM^i\\ A[0]G(M)&=\sum_{i=0}^{k-1}g_i(A[0]M^i)\\ A[0]G(M)&=\sum_{i=0}^{k-1}g_iA[i] \end{aligned}\]

而事實上我們要求的並不是最終的向量\(A[n]\),而只有向量\(A[n]\)的最后一項。
因此:

\[f[n]=\sum_{i=0}^{k-1}g_if[i] \]

那么這樣一來我們把矩陣的轉移變成了簡單的數之間的轉移。
時間復雜度為\(O(klogklogn)\)

似乎這篇文章里面有些細節上的東西寫得不是很好,意會一下就好了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM