• 「NOTE」常系数齐次线性递推


    要不是考到了,我还没发现这玩意我不是很会……


    # 前置

    • 多项式取模;
    • 矩阵快速幂。

    # 常系数齐次线性递推

    描述的是这么一个问题,给定数列 (c_1,c_2,dots,c_k) 以及数列 (f) 的前 (k)(f_0,f_1,dots,f_{k-1}),已知 (f) 有如下递推公式:

    [egin{aligned} (nge m)&&f_{n}=sum_{i=1}^kc_if_{n-i} end{aligned} ]

    (f_n mod 998244353),其中 (n) 可以很大,(k)(10^5) 左右的数。

    • 常系数:递推式的系数 (c_i) 均为常数;
    • 齐次:这意味着递推式没有常数项(如果有常数项就别想了);
    • 线性:(f_i) 的指数都为 (1)

    # 算法原理

    对于这种系数为常数的问题,我们有一个通用的解法 —— 矩阵快速幂:

    [egin{bmatrix}f_{n}\f_{n + 1}\vdots\f_{n + k - 1}end{bmatrix}=egin{bmatrix}0&1&0&cdots&0\0&0&1&cdots&0\0&0&0&cdots&0\vdots&vdots&vdots&ddots&vdots\c_k&c_{k - 1}&c_{k - 2}&cdots&c_1end{bmatrix} imesegin{bmatrix}f_{n - 1}\f_{n}\vdots\f_{n + k - 2}end{bmatrix} ]

    记最后那个 (k imes k) 的转移方阵为 (A),初始列向量为 (St)。常规的计算方法即计算

    [A^n imes St ]

    复杂度 (mathcal O(k^3log n)),主要的瓶颈在于矩阵乘法。

    下面要介绍的算法给出了这样一种构造,其中 ({c_i}) 是针对 (A^n)(注意不仅与 (A) 有关,还与指数 (n) 有关)构造的数列 ——

    [egin{aligned} &A^n=sum_{i=0}^{k-1}c_iA^i\ &A^n imes St=sum_{i=0}^{k-1}c_iA^i imes St end{aligned} ]

    目前看来好像没有什么茄子用,仍然需要计算矩乘。但是我们真的需要 (A^n imes St) 这整个向量吗?实际上我们只需要 (f_n),即 (A^n imes St) 的第一项。

    再看看这个式子就可以发现它的用处了:

    [(A^n imes St)_1=sum_{i=0}^{k-1}(c_iA^i imes St)_1=sum_{i=0}^{k-1}c_i(A^i imes St)_1 ]

    (A^i imes St) 的实际意义是将 (St) 转移 (i) 次。所以 ((A^i imes St)_1=f_i),也即

    [f_n=sum_{i=0}^{k-1}c_if_i ]

    这样就免去了矩乘。

    这就是这个算法的全部内容了?还剩下一个问题,({c_i}) 怎么构造?

    定义函数 (C(x)) 如下,则要求 (C(A)=A^n)

    [C(x)=sum_{i=0}^{k - 1}c_ix^i ]

    接下来是一些魔法……如果我们有函数 (F(x)) 满足

    [F(A)=sum_{i=0}^{k}f_iA^i=0 ]

    且有 (G(x)) 满足:

    [x^n=G(x)F(x)+C(x) o C(x)=x^nmod F(x) ]

    易得

    [A^n=G(A)F(A)+C(A)=C(A) ]

    利用多项式取模对快速幂稍加改造就可以计算 (C(x))

    「稍 加 改 造」

    说起来倒也简单,把多项式 $x$ 拿来做快速幂,对 $F(x)$ 取模。

    然后我们发现又需要构造 (F(x))……如果要对一个一般的方阵求 (F(A)=0) 那确实很难,但常系数齐次线性递推的转移矩阵 (A) 因为它的结构特殊,有一个简洁的构造:

    • (f_k=1)
    • (f_{i}=-c_{k-i})(0le ilt k))。

    至于为什么这样构造,就涉及到矩阵的特征向量的内容,和这个算法本身没有太紧的关联。有兴趣的读者可以参考 shadowice1984 的洛谷博客


    THE END

    Thanks for reading!

    我也曾 隐约想过 从这世界逃离
    因为有无数次 和最优解失之交臂
    那时耀眼的自己 定不会轻易容许
    骄傲变得同墙角霉菌 不差毫厘

    ——《我也曾想过一了百了(中文填词)》 By 洛天依

    > Link 我也曾想过一了百了 - Bilibili

    欢迎转载٩(๑❛ᴗ❛๑)۶,请在转载文章末尾附上原博文网址~
  • 相关阅读:
    LeetCode OJ--Best Time to Buy and Sell Stock II
    LeetCode OJ--Best Time to Buy and Sell Stock
    路飞学城Python-Day37(practise)
    路飞学城Python-Day37
    路飞学城Python-Day36
    路飞学城Python-Day35
    路飞学城Python-Day35
    “肥宅快乐数”-python暴力版
    路飞学城Python-Day34
    路飞学城Python-Day33
  • 原文地址:https://www.cnblogs.com/LuckyGlass-blog/p/14791974.html
Copyright © 2020-2023  润新知