标签:
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
从网上找了3段为什么是1e9+6的解释:
A^B %C 这题的C是质素,而且A,C是互质的。
所以直接A^(B%(C-1)) %C
比较一般的结论是 A^B %C=A^( B%phi(C)+phi(C) ) %C B>=phi(C)
求a^fib(n)%mod,mod=10^9+7,由于mod是一个大质数,根据费马小定理,a^(mod-1)=1(mod m),所以a^x有一个循环节,这个循环节为10^9+6
模数之所以为1000000006是因为根据费马小定理可得A^euler(M) = 1 (mod M),其中M为素数。 所以A^N = A^(N % euler(M))(mod M),而1000000007为素数,euler(1000000007)= 1000000006,所以模数是1000000006。
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 }
hdu 4549 M斐波拉契 (矩阵快速幂 + 费马小定理)
标签:
原文地址:http://www.cnblogs.com/-Buff-/p/4534811.html