FFT 优化常系数齐次线性递推式
\(f_i\) 序列满足 \(f_i=\displaystyle\sum_{j=1}^k c_jf_{i-j}\)。\(k\le 32000,n\le 10^9\)。
已知 \(f_1\sim f_k\) 和 \(c_1\sim c_k\)。求 \(f_n\)。
这称为 "\(k\) 次齐次常系数线性递推式"。
如果 \(k\) 比较小,可以用矩阵快速幂;但 \(k\) 太大,一次矩阵乘法都很慢。我们可以用 FFT 优化它。复杂度 \(O(k\log k\log n)\)。
先回忆一下矩阵快速幂。
特征多项式:一个矩阵 \(M\) 的特征多项式 \(\lambda\) 满足 \(det(\lambda I-M)=0\)。(\(det(\lambda I-M)\) 是一个关于 \(\lambda\) 的多项式)
记中间的转移矩阵为 \(M\)。它的特征多项式为 \(\phi(\lambda)=\lambda^k-c_1\lambda^{k-1}-c_2\lambda^{k-2}-\cdots-c_k\)。
克雷-哈密尔顿(Cayley-Hamiltion)定理:\(\phi(M)\) 得全零矩阵。
设 \(x^n=p(x)\times \phi(x)+r(x)\)(带余除法)。\(\deg r(x)\le k-1=\deg \phi(x)\)。
假设 \(r(x)\) 求出来了。令 \(x\) 为矩阵 \(M\),\(M^n=p(M)\cdot \phi(M)+r(M)\);由定理,\(\phi(M)=0\)。所以 \(M^n=r(M)=\sum r_iM^i\)。
设
则 \(F_{n+k-1}=\displaystyle\sum_{i=0}^{k-1}r_iM^iF_{k-1}=\sum_{i=0}^{k-1}r_i\cdot F_{i+k-1}\)
\(\therefore f_n=\displaystyle\sum_{i=0}^{k-1}r_if_i\),\(O(k)\) 可求。
最后一个问题:\(r(x)\) 怎么算?
如果用带余除法算,\(O(n\log n)\);而 \(n\le 1e9\) 会爆炸。
\(x^{a+b}\% \phi(x)=x^a\cdot x^b \% \phi(x)=((x^a\% \phi(x))\cdot (x^b\% \phi(x))\% \phi(x)\)
而 \(x^a\% \phi(x)\) 和 \(x^b\% \phi(x)\) 都是 \(k\) 次,因此如果求得 \(x^a\% \phi(x)\) 和 \(x^b\% \phi(x)\),就能 \(O(k\log k)\) 求带余除法。
那么让 \(x^a\%\phi(x)\) 继续递归即可。递归 \(O(\log n)\) 层。
复杂度 \(O(\log n\cdot k\log k)\)。