• 矩阵加速递推


    关于矩阵加速数列递推:

    给定一个递推数列 (f[i] = a_1*f[i-1] + a_2*f[i-2] … a_k*f[i-k]) ,我们普通计算的话肯定是逐个计算,复杂度较大。

    我们可以用矩阵表示:

    [ left[ egin{matrix} f[i] \ f[i-1] \ … \ f[i-k] end{matrix} ight] ]

    为了递推出 (f[n]) ,我们需要找到一个系数矩阵 (A) 使得:

    [ left[ egin{matrix} f[i] \ f[i-1] \ … \ f[i-k] end{matrix} ight] = A imes left[ egin{matrix} f[i-1] \ f[i-2] \ … \ f[i-k-1] end{matrix} ight] ]

    就可以这样计算:

    [ left[ egin{matrix} f[n+k] \ f[n+k-1] \ … \ f[n] end{matrix} ight] = A^{n-1} imes left[ egin{matrix} f[k] \ f[k-1] \ … \ f[1] end{matrix} ight] ]

    通过矩阵快速幂来计算 (A^n) 可以减小复杂度,问题是如何找到一个 (A) 矩阵

    容易发现,(A)矩阵可以这样构造:

    [ left[ egin{matrix} a_1 & a_2 & … & a_k-1 & a_k \ 1 & 0 & … & 0 & 0 \ 0 & 1 & … & 0 & 0 \ … & … & … & … & … \ 0 & 0 & … & 1 & 0 end{matrix} ight] ]

    即第一行为系数,从 (A_{2,1}) 开始的一条斜线为 (1), 其余为 (0),这样构造可以保证 (f[i]) 被计算出来了,而其余的元素都继承了上一个矩阵的值。

    至此,我们可以愉快地用矩阵加速递推数列了。

  • 相关阅读:
    1015: [JSOI2008]星球大战starwar
    Tyvj P1813 [JSOI2008]海战训练
    1012: [JSOI2008]最大数maxnumber
    1430: 小猴打架
    1270: [BeijingWc2008]雷涛的小猫
    1202: [HNOI2005]狡猾的商人
    1059: [ZJOI2007]矩阵游戏
    3039: 玉蟾宫
    1303: [CQOI2009]中位数图
    1002: [FJOI2007]轮状病毒
  • 原文地址:https://www.cnblogs.com/alecli/p/10004417.html
Copyright © 2020-2023  润新知