0258 延迟斐波那契
* * * *
拉格朗日计划
* * * *
延迟斐波那契

考虑如下的数列:$g_0=g_1=\ldots=g_{1999}=1$,且 $$g_k=g_{k-2000}+g_{k-1999}, \quad k\ge 2000$$ 求$g_{10^{18}} \bmod 20092010$。

本题难度:



解答

显然需要将这一线性递推关系写成矩阵形式 $$\begin{bmatrix}g_{2000}\\ g_{1999}\\ g_{1998}\\ \vdots\\ g_2\\ g_1\end{bmatrix}=\begin{bmatrix} 0 & 0 & \cdots & 0 &1 & 1\\ 1 & 0 & \cdots & 0 & 0 & 0\\ 0 & 1 & \cdots & 0 & 0 & 0\\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots\\ 0 & 0 & \cdots & 1 & 0 & 0\\ 0 & 0 & \cdots & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} g_{1999}\\ g_{1998}\\ g_{1997}\\ \vdots\\ g_1 \\ g_0 \end{bmatrix},$$ 再用矩阵快速幂作计算。不过一般而言,矩阵乘法的复杂度是$O(n^3)$,本题中的矩阵为2000阶,仅使用快速幂还不足以计算出结果。

记等式右侧的矩阵为A,注意到$A^{2000}=I+A$(I是单位阵),因此A的任意幂$A^m$都可以表示为$I,A,\ldots, A^{1999}$的线性组合,从将矩阵乘法转化为多项式乘法。

此时再结合快速幂即可得结果$12747994$。

注:本题计算量很大, 也很难估计和打印进度,需要耐心等待。

size=2000
N=10**18
m=20092010

p=[0,1]+[0]*(size-2)
f=[1,1]+[0]*(size-2)
x=[1]+[0]*(size-1)

def cal(a,b):
    c=[0]*(size*2)
    for i in range(size):
        for j in range(size):
            c[i+j]=(c[i+j]+a[i]*b[j])%m
    for i in range(size*2-1, size-1,-1):
        for j in range(size):
            c[i+j-size]=(c[i+j-size]+c[i]*f[j])%m
    for i in range(size):
        b[i]=c[i]

while N:
    if N%2>0:
        cal(p,x)
    cal(p,p)
    N>>=1

print sum(x)%m