hdu4549 M-fib数列 费马小定理+矩阵快速幂

hdu4549 M-fib数列   费马小定理+矩阵快速幂

M斐波那契数列

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


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^fib(n-2) * b^fib(n-1) %p。
由于幂太大,所以就用费马小定理。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>

using namespace std;

const int maxn=1000100;
const int INF=(1<<29);
typedef unsigned long long ll;
const ll p=1000000007;
ll a,b,n;
struct Matrix
{
    ll a[2][2];
    friend Matrix operator*(Matrix A,Matrix B)
    {
        Matrix C={0,0,0,0};
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    C.a[i][j]=(C.a[i][j]%(p-1)+((A.a[i][k]%(p-1))*(B.a[k][j]%(p-1)))%(p-1))%(p-1);
                }
            }
        }
        return C;
    }
};

Matrix qpow_M(Matrix n,ll k)
{
    Matrix res={1,0,0,1};
    while(k){
        if(k&1) res=res*n;
        n=n*n;
        k>>=1;
    }
    return res;
}

ll fib(ll n)
{
    Matrix tmp={1,1,1,0};
    Matrix res=qpow_M(tmp,n);
    return res.a[0][0];
}

ll qpow(ll n,ll k,ll p)
{
    ll res=1;
    while(k){
        if(k&1) res=((res%p)*(n%p))%p;
        n=((n%p)*(n%p))%p;
        k>>=1;
    }
    return res;
}

ll solve(ll a,ll n)
{
    ll k=fib(n);
    return qpow(a,k,p);
}

ll F(ll n)
{
    ll A=solve(a,n-2);
    ll B=solve(b,n-1);
    return(A*B)%p;
}

int main()
{
    while(~scanf("%I64d%I64d%I64d",&a,&b,&n)){
        if(a==0){
            printf("%I64d\n",n==1?b:0);
            continue;
        }
        if(b==0){
            printf("%I64d\n",n?0:a);
            continue;
        }
        if(n>=2) printf("%I64d\n",F(n));
        else printf("%I64d\n",n?b:a);
    }
    return 0;
}
View Code

 

 

posted @ 2015-08-23 20:38  __560  阅读(301)  评论(0编辑  收藏  举报