【矩阵乘法加速递推】 SSL 1531 斐波那契数列

大意

f[i]=f[i2]+f[i1]+n+1 f [ i ] = f [ i − 2 ] + f [ i − 1 ] + n + 1
f[1]=f[2]=1 f [ 1 ] = f [ 2 ] = 1 f[n] mod 9973 f [ n ]   m o d   9973


思路

考虑矩阵乘法加速递推

观察发现,这简直就是一个矩阵乘法板子,我们从这个方向想即可

首先因为有四个系数,所以我们建立一个 4×4 4 × 4 的矩阵,然后去想每个数需要变成几就非常容易想到中间矩阵了

f[i2]f[i1]=1 f [ i − 2 ] → f [ i − 1 ] = 1
f[i1]f[i] f [ i − 1 ] → f [ i ]
ii+1 i → i + 1
11 1 → 1
这样,所有四个系数的转移都想好了,现在只需按这个规则转移即可,如图
【矩阵乘法加速递推】 SSL 1531 斐波那契数列_第1张图片


代码

#include
#include
#define ymw 9973
using namespace std;int n;
struct node{int a[4][4],r,c;};
inline node mul(node x,node y)//矩阵乘法
{
    node z;
    memset(&z,0,sizeof(z));
    for(register int i=0;ifor(register int j=0;jfor(register int k=0;kreturn z;
}
inline int ksm(register int y)
{
    node x,ans;
    memset(&x,0,sizeof(x));
    memset(&ans,0,sizeof(ans));
    x.r=x.c=ans.r=ans.c=4;
    x.a[1][0]=1;
    x.a[0][1]=x.a[1][1]=x.a[2][1]=x.a[3][1]=1;
    x.a[2][2]=x.a[3][2]=1;
    x.a[3][3]=1;
    ans.a[0][0]=ans.a[0][1]=ans.a[0][3]=1;
    ans.a[0][2]=3;//注意,初始是从第三个矩阵开始算
    while(y)
    {
        if(y&1) ans=mul(ans,x);
        x=mul(x,x);
        y>>=1;
    }
    return ans.a[0][0];
}
signed main()
{
    scanf("%d",&n);
    printf("%d",ksm(n-1));
}

你可能感兴趣的:(矩阵乘法)