HDU 4549 M斐波那契数列

来源:互联网 发布:实时弹幕软件 编辑:程序博客网 时间:2024/06/06 04:36

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


题意:M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的值吗?


思路:写一下前几项,发现指数其实就是斐波那契数列,Fn = a^f(n-1) + b ^ f(n) ,即先用矩阵快速幂求出幂数,在用快速幂计算a^i,b^j。


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod 1000000007int a,b,n;struct node{    LL p[2][2];};node multi( node &x , node &y ){    node ans;    rep(i,0,1)        rep(j,0,1)        {            ans.p[i][j] = 0;            rep(k,0,1)                ans.p[i][j] = ( ans.p[i][j] + x.p[i][k] * y.p[k][j] ) % ( mod - 1 );        }    return ans;}void fib( LL &ta , LL &tb , int t ){    node ans,temp;    temp.p[0][0] = 0;    temp.p[0][1] = temp.p[1][0] = temp.p[1][1] = 1;    ans.p[0][0] = ans.p[1][1] = 1;    ans.p[0][1] = ans.p[1][0] = 0;    while( t )    {        if ( t & 1 ) ans = multi( ans , temp );        temp = multi( temp , temp );        t >>= 1;    }    ta = ans.p[1][0];    tb = ans.p[1][1];}LL pow_mod( LL a , LL b ){    a %= mod;    LL ans = 1;    while( b )    {        if ( b & 1 ) ans = ( ans * a ) % mod;        a = ( a * a ) % mod;        b >>= 1;    }    return ans;}void solve(){    LL ta,tb;    fib( ta , tb , n-1 );    LL ans = pow_mod( a , ta );    ans = ( ans * pow_mod( b , tb ) ) % mod;    printf("%I64d\n",ans);}int main(){    while( scanf("%d%d%d",&a,&b,&n) == 3 )    {        if ( n == 0 ) printf("%d\n",a % mod);        else if ( n == 1 ) printf("%d\n",b % mod);        else solve();    }    return 0;}




0 0
原创粉丝点击