hdu 4549 M斐波那契数列

click here ~~

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取模后的值即可,每组数据输出一行。

题目大意:这是中文。。。。

解题思路:采用斐波那契的思想,就是求一个f(n) % mod;
f(0) = a, f(1) = b;
f(n) = f(n-1)*f(n-2);
最后化为f(n) = ((a^x)*(b^y)) %mod;
而x与y是斐波那契数,而且mod是素数;
所以根据公式:a^b%c == a^(b %phi(c)+phi(c))%c;

又因为c是素数所以直接化为:
a^b%c == a^(b %(c-1))%(c-1);

上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int mod = 1e9 + 7;
const int maxn = 2;

typedef long long LL;

struct Matrix
{
    LL m[maxn][maxn];
};
///单位阵
Matrix I = {1, 0,
            0, 1
           };
///目标阵           
Matrix P = {0, 1,
            1, 1
           };
///矩阵乘法           
Matrix matrix_mul(Matrix a, Matrix b)
{
    int i, j, k;
    Matrix c;
    for(i=0; i<maxn; i++)
    {
        for(j=0; j<maxn; j++)
        {
            c.m[i][j] = 0;
            for(k=0; k<maxn; k++)
                c.m[i][j] += (a.m[i][k] * b.m[k][j]) % (mod-1);
            c.m[i][j] %= (mod-1);
        }
    }
    return c;
}
///矩阵快速幂
Matrix quick_M(LL m)
{
    Matrix ans = I, b = P;
    while(m)
    {
        if(m & 1)
            ans = matrix_mul(ans, b);
        m >>= 1;
        b = matrix_mul(b, b);
    }
    return ans;
}
///快速幂
LL quick_m(LL a, LL b)
{
    LL ans = 1;
    LL tmp = a%mod;
    while(b)
    {
        if(b & 1)
        {
            ans *= tmp;
            ans %= mod;
        }
        tmp *= tmp;
        tmp %= mod;
        b >>= 1;
    }
    return ans;
}

int main()
{
    int a, b, n;
    while(~scanf("%d%d%d",&a,&b,&n))
    {
        Matrix p = quick_M(n);
        int ans = (quick_m(a,p.m[0][0]) * quick_m(b,p.m[1][0]))%mod;
        cout<<ans<<endl;
    }
    return 0;
}
/**
Sample Input

0 1 0
6 10 2


Sample Output

0
60
**/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值