【数论 矩阵快速幂 费马小定理】 hdu 4549 M斐波那契数列

M斐波那契数列

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 8046    Accepted Submission(s): 2389


Problem Description
M斐波那契数列F[n]是一种整数数列,它的定义如下:

F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )

现在给出a, b, n,你能求出F[n]的值吗?
 

 

Input
输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
 

 

Output
对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。
 

 

Sample Input
0 1 0 6 10 2
 

 

Sample Output
0 60
 
枚举几项就能发现,F[n]=a^(f[n-1])*b^(f[n])
然后根据费马小定理
把%p转化成-> F[n]=a^(f[n-1]%(p-1))*b^(f[n]%(p-1))
 
然后用矩阵快速幂算一下就好
 
 
代码
 
#include <iostream>
#include <cmath>
#include <cstdio>
#define ll long long
#define MOD 1000000007

using namespace std;

const int N=2,M=2,P=2;

ll qmod(ll a,ll b,ll mod)
{
    ll ans=1;
    a=a%mod;
    while(b)
    {
        if(b&1)
        {
            ans=(ans*a)%mod;
        }
        b=b/2;
        a=(a*a)%mod;
    }
    return ans;
}

struct Matrix
{
    ll m[N][N];
};

Matrix A={1,1,
          1,0};

Matrix I={1,0,
          0,1};

Matrix mult(Matrix a,Matrix b,ll mod)
{
    Matrix ans;
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<M;j++)
        {
            ans.m[i][j]=0;
            for(int k=0;k<P;k++)
            {
                ans.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;
            }
            ans.m[i][j]%=mod;
        }
    }
    return ans;
}

Matrix power(Matrix a,ll b,ll mod)
{
    Matrix ans=I,p=a;
    while(b)
    {
        if(b&1)
        {
            ans=mult(ans,p,mod);
        }
        b=b/2;
        p=mult(p,p,mod);
    }
    return ans;
}

int main()
{
    ll a,b,n;
    while(cin>>a>>b>>n)
    {
        ll aa,bb;
        Matrix ans=power(A,n-1,MOD-1);
        bb=ans.m[0][0];
        aa=ans.m[1][0];
        a=a%MOD;
        b=b%MOD;
        if(n==0) bb=0;
        ll ans1=qmod(a,aa,MOD);
        ll ans2=qmod(b,bb,MOD);
        ll num=(ans1*ans2)%MOD;
        cout<<num<<endl;
    }
    return 0;
}

 

posted @ 2020-11-25 10:47  andyc_03  阅读(77)  评论(0编辑  收藏  举报