1. 程式人生 > >hdu 4549 M斐波那契數列(費馬小定理+矩陣快速冪)

hdu 4549 M斐波那契數列(費馬小定理+矩陣快速冪)

F(n)=a^F(n-1)*b^F(n-2)%mod

因為a和b都與mod互素,因此用費馬小定理可以得到

F(n)=a^(f(n-1)%mod-1)*b^(f(n)%mod-1) %mod 

因此用一次矩陣快速冪和兩次快速冪即可。

#include<iostream>
using namespace std;
typedef long long LL;
#define mod1 1000000006
struct mat{
    LL a[2][2];
};

mat multi(mat x,mat y)          //矩陣乘法 
{
    mat z;
    for(int i=0
;i<2;i++) for(int j=0;j<2;j++) { LL ans=0; for(int k=0;k<2;k++) ans=(ans+x.a[i][k]*y.a[k][j])%mod1; z.a[i][j]=ans%mod1; } return z; } mat mat_quickmod(LL n) //矩陣快速冪 { mat x,y; x.a[0][0]=x.a[1][1]=1,x.a[0][1]=x.a[1][0
]=0; y.a[0][0]=0,y.a[0][1]=y.a[1][0]=y.a[1][1]=1; while(n) { if(n%2) x=multi(x,y); y=multi(y,y); n/=2; } return x; } LL quickmod(LL x,LL n,LL mod) //快速冪 { LL ans=1; while(n) { if(n%2) ans=ans*x%mod; x=x*x%mod; n/=2
; } return ans; } int main() { LL x,y,n,mod=1000000007; while(cin>>x>>y>>n) { mat k=mat_quickmod(n); LL ans=quickmod(x,k.a[0][0],mod)*quickmod(y,k.a[1][0],mod)%mod; cout<<ans<<endl; } return 0; }