M斐波那契数列

一、题目

在这里插入图片描述

二、解法

可以把这个变形的斐波那契理解为指数上的正常斐波那契,分别做两次矩阵加速,第一次初始值为 1 , 0 1,0 1,0,第二次初始值为 0 , 1 0,1 0,1,把两次的 a F ( n ) , b F ( n ) a^{F(n)},b^{F(n)} aF(n),bF(n)求乘积即可。
现在的问题是 F ( n ) F(n) F(n)太大会爆,考虑到模数是一个质数 1 e 9 + 7 1e9+7 1e9+7,利用欧拉定理 a φ ( n ) = 1 a^{\varphi(n)}=1 aφ(n)=1,对指数直接取模 1 e 9 + 6 1e9+6 1e9+6即可,最后再算快速幂,取模 1 e 9 + 7 1e9+7 1e9+7

#include <cstdio>
#include <cstring>
#define int long long
const int MOD = 1e9+7;
const int phi = 1e9+6;
int read()
{
    int x=0,flag=1;
    char c;
    while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
    while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*flag;
}
struct Matrix
{
    int n,m,a[3][3];
    Matrix() {n=m=0;memset(a,0,sizeof a);}
    Matrix operator * (const Matrix &B) const
    {
        Matrix res;
        res.n=n;res.m=B.m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                for(int k=1;k<=B.m;k++)
                    res.a[i][k]=(res.a[i][k]+a[i][j]*B.a[j][k])%phi;
        return res;
    }
}F,A;
Matrix Mpow(Matrix a,int b)
{
    Matrix res;
    res.n=a.n;res.m=a.m;
    for(int i=1;i<=res.n;i++)
        res.a[i][i]=1;
    while(b>0)
    {
        if(b&1) res=res*a;
        a=a*a;
        b>>=1;
    }
    return res;
}
int qkpow(int a,int b)
{
    int res=1;
    while(b>0)
    {
        if(b&1) res=res*a%MOD;
        a=a*a%MOD;
        b>>=1;
    }
    return res;
}
int a,b,n,ans;
signed main()
{
    while(~scanf("%d %d %d",&a,&b,&n))
    {
        if(n<2)
        {
            if(n==0) printf("%d\n",a);
            else printf("%d\n",b);
            continue;
        }
        F.n=1;F.m=2;A.n=2;A.m=2;
        A.a[1][1]=A.a[1][2]=A.a[2][1]=1;
        F.a[1][2]=1;
        F.a[1][1]=0;
        ans=qkpow(a,(F*Mpow(A,n-1)).a[1][1]);
        F.a[1][1]=1;
        F.a[1][2]=0;
        ans=ans*qkpow(b,(F*Mpow(A,n-1)).a[1][1])%MOD;
        printf("%d\n",ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值