hdu 4549 M斐波拉契 (矩阵快速幂 + 费马小定理)
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
费马小定理:(a^b)%mod =a^( b%(mod-1) )%mod
这题用矩阵快速幂求指数,求矩阵的幂,相当于求公式里的b
A^B %MOD 这题的MOD是素数,而且A,MOD是互质的。(A的最大范围是1e9)
所以直接A^(B%(MOD-1)) %MOD
1 # include <iostream> 2 # include <cstdio> 3 # include <algorithm> 4 # include <map> 5 # include <cmath> 6 # define LL long long 7 using namespace std ; 8 9 const int MOD = 1000000007 ; 10 11 struct Matrix 12 { 13 LL mat[2][2]; 14 }; 15 16 Matrix mul(Matrix a,Matrix b) //矩阵乘法 17 { 18 Matrix c; 19 for(int i=0;i<2;i++) 20 for(int j=0;j<2;j++) 21 { 22 c.mat[i][j]=0; 23 for(int k=0;k<2;k++) 24 { 25 c.mat[i][j]=(c.mat[i][j] + a.mat[i][k]*b.mat[k][j])%(MOD-1); //费马小定理 26 } 27 } 28 return c; 29 } 30 Matrix pow_M(Matrix a,int k) //矩阵快速幂 31 { 32 Matrix ans; 33 memset(ans.mat,0,sizeof(ans.mat)); 34 for (int i=0;i<2;i++) 35 ans.mat[i][i]=1; 36 Matrix temp=a; 37 while(k) 38 { 39 if(k&1)ans=mul(ans,temp); 40 temp=mul(temp,temp); 41 k>>=1; 42 } 43 return ans; 44 } 45 46 LL pow_m(LL p, LL k) 47 { 48 49 LL ans = 1; 50 while(k) { 51 if (k & 1) ans = ans * p % MOD; 52 p = (LL)p*p % MOD; 53 k >>= 1; 54 } 55 return ans; 56 } 57 58 int main () 59 { 60 // freopen("in.txt","r",stdin) ; 61 int a,b,n; 62 Matrix t ; 63 t.mat[0][0] = 0 ; 64 t.mat[0][1] = t.mat[1][0] = t.mat[1][1] = 1 ; 65 while(scanf("%d%d%d",&a,&b,&n)!=EOF) 66 { 67 Matrix p=pow_M(t,n); 68 int ans=(pow_m(a,p.mat[0][0])*pow_m(b,p.mat[1][0]))%MOD; 69 printf("%d\n",ans); 70 } 71 72 73 return 0 ; 74 }