M斐波那契数列(矩阵快速幂+费马小定理)

M斐波那契数列

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


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
 

 

Source
 

 

题意:不解释,中文题。

思路:费马小定理+矩阵快速幂

 

 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4549 

转载请注明出处:寻找&星空の孩子

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL __int64
const __int64 mod=1000000007;


struct matrix
{
    LL mat[2][2];
};
matrix multiply(matrix a,matrix b)
{
    matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            if(a.mat[i][j]==0)continue;
            for(int k=0;k<2;k++)
            {
                if(b.mat[j][k]==0)continue;
                c.mat[i][k]=(c.mat[i][k]+a.mat[i][j]*b.mat[j][k])%(mod-1);//加法不能简写成..+=...%..
            }
        }
    }
    return c;
}
matrix matrixquicklymod(matrix x,LL m)
{
    matrix res;
//    memset(res.mat,0,sizeof(res.mat));
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            res.mat[i][j]=(i==j);
    while(m)
    {
        if(m&1) res=multiply(res,x);
        m>>=1;
        x=multiply(x,x);
    }
    return res;
}

LL qmod(LL x, LL y)
{
    LL z=1;
    while(y)
    {
        if(y&1) z=(z*x)%mod;
        y>>=1;
        x=(x*x)%mod;
    }
    return z;
}
int main()
{
    LL a,b,n,ma,mb;
    while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF)
    {
        matrix ans;
        ma=mb=1;//
        ans.mat[0][0]=1;
        ans.mat[0][1]=1;
        ans.mat[1][0]=1;
        ans.mat[1][1]=0;
        if(n==0)
            printf("%I64d\n",a%mod);
        else if(n==1)
            printf("%I64d\n",b%mod);
        else if(n==2)
            printf("%I64d\n",((a%mod)*(b%mod))%mod);
        else
        {
            ans=matrixquicklymod(ans,n-2);
            mb=ans.mat[0][0]+ans.mat[1][0];
            ma=ans.mat[0][1]+ans.mat[1][1];
            ma=ma%(mod-1);
            mb=mb%(mod-1);
            a=qmod(a,ma);
            b=qmod(b,mb);
            printf("%I64d\n",((a%mod)*(b%mod))%mod);
        }
    }
    return 0;
}

慢慢提升吧。。。。。少年!

posted @ 2015-03-13 19:49  寻找&星空の孩子  阅读(788)  评论(0编辑  收藏  举报