hdu4549 M-fib数列 费马小定理+矩阵快速幂
M斐波那契数列
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 2122 Accepted Submission(s): 606
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]的值吗?
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 )
每组数据占一行,包含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
思路:随便列出前几项就能发现规律了。。F(n)=a^fib(n-2) * b^fib(n-1) %p。
由于幂太大,所以就用费马小定理。。。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int maxn=1000100; const int INF=(1<<29); typedef unsigned long long ll; const ll p=1000000007; ll a,b,n; struct Matrix { ll a[2][2]; friend Matrix operator*(Matrix A,Matrix B) { Matrix C={0,0,0,0}; for(int i=0;i<2;i++){ for(int j=0;j<2;j++){ for(int k=0;k<2;k++){ C.a[i][j]=(C.a[i][j]%(p-1)+((A.a[i][k]%(p-1))*(B.a[k][j]%(p-1)))%(p-1))%(p-1); } } } return C; } }; Matrix qpow_M(Matrix n,ll k) { Matrix res={1,0,0,1}; while(k){ if(k&1) res=res*n; n=n*n; k>>=1; } return res; } ll fib(ll n) { Matrix tmp={1,1,1,0}; Matrix res=qpow_M(tmp,n); return res.a[0][0]; } ll qpow(ll n,ll k,ll p) { ll res=1; while(k){ if(k&1) res=((res%p)*(n%p))%p; n=((n%p)*(n%p))%p; k>>=1; } return res; } ll solve(ll a,ll n) { ll k=fib(n); return qpow(a,k,p); } ll F(ll n) { ll A=solve(a,n-2); ll B=solve(b,n-1); return(A*B)%p; } int main() { while(~scanf("%I64d%I64d%I64d",&a,&b,&n)){ if(a==0){ printf("%I64d\n",n==1?b:0); continue; } if(b==0){ printf("%I64d\n",n?0:a); continue; } if(n>=2) printf("%I64d\n",F(n)); else printf("%I64d\n",n?b:a); } return 0; }