矩阵乘法——Fibonacci第n项

问题 B: 【例题2】Fibonacci第n项

时间限制: 1 Sec  内存限制: 128 MB
提交: 11  解决: 4
[提交][状态][讨论版][命题人:quanxing]

题目描述

大家都知道Fibonacci数列吧,f[1]=1,f[2]=1,f[3]=2,f[4]=3.......也就是f[n]=f[n-1]+f[n-2]。现在,问题很简单,输入n和m,求第n项取模m。

输入

输入n,m。

1<=n<=2 000 000 000 。

1<=m<=1 000 000 010 。

输出

输出第n项取模m

样例输入

5 1000

样例输出

5

f[i]=1*f[i-1]+1*f[i-2]

f[i-1]=1*f[i-1]+0*f[i-2]

 \binom{f[i]}{f[i-1]}=\begin{pmatrix} 1 &1 \\ 1&0 \end{pmatrix}*\binom{f[i-1]}{f[i-2]}=\begin{pmatrix} 1 &1 \\ 1&0 \end{pmatrix}*\begin{pmatrix} 1 &1 \\ 1&0 \end{pmatrix}*\binom{f[i-2]}{f[i-3]}

\binom{f[n]}{f[n-1]}=\begin{pmatrix} 1 &1 \\ 1&0 \end{pmatrix}^{n-2}*\binom{f[2]}{f[1]}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
long long int n,m;
struct node//结构体存储矩阵
{
    long long int g[5][5];
}f,res;
void init(node &x)//构造单位矩阵
{
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
        if(i==j)x.g[i][j]=1;
        else x.g[i][j]=0;
}
void multiple(node &x,node &y,node &z)//矩阵乘法(把矩阵x乘以矩阵y的结果储存到矩阵z)
{
    memset(z.g,0,sizeof(z.g));
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
        if(x.g[i][j])
    {
        for(int k=1;k<=2;k++)
        {
            z.g[i][k]+=x.g[i][j]*y.g[j][k];//z第i行第k列的值是x第i行和y第k列对应值的乘积之和
            if(z.g[i][k]>=m)z.g[i][k]%=m;//对m取模
        }
    }
}
void quickpow(int k)//快速幂
{
    init(res);
    node temp=f,t;
    while(k)
    {
        if(k&1)//k是奇数,temp^k=temp*temp^(k/2)*temp^(k/2)
        {
            multiple(res,temp,t);//res=res*temp
            res=t;
        }
        multiple(temp,temp,t);//temp=temp*temp
        temp=t;
        k>>=1;//k=k/2
    }
}
long long int solve()
{
    if(n<=2)return 1;//F[1]=1,F[2]=1
    quickpow(n-2);
    long long int ret=res.g[1][1]*1+res.g[1][2]*1;//计算矩阵第一行元素f[n]
    if(ret>=m)ret%=m;//取模运算
    return ret;
}
int main()
{
    scanf("%d%d",&n,&m);
    f.g[1][1]=1;
    f.g[1][2]=1;
    f.g[2][1]=1;
    f.g[2][2]=0;
    long long int ans=solve();
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40729773/article/details/81410064