常係數齊次線性遞推

常係數齊次線性遞推

要幹啥

已知
\[f[n]=\sum_{i=1}^k C_if[n-i]\]
\(f[n]\)的值,\(n\le 10^9,k\le 20000\),答案取模。spa

暴力作法

若是複雜度\(O(nk)\)容許的話,顯然是能夠直接\(dp\)轉移的。
\(k\)很小的時候,轉移寫成矩陣形式,假設轉移矩陣爲\(M\),能夠獲得:\(\displaystyle f[n]=f[0]*M^n\),這裏的\(f\)是向量的形式。
複雜度爲\(O(k^3logn)\)class

因此到底要怎麼作

顯然咱們已知矩乘的時候是一個\(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)\)di

彷佛這篇文章裏面有些細節上的東西寫得不是很好,意會一下就行了。時間

相關文章
相關標籤/搜索