HDU 4549 新增5_M斐波那契数列 矩阵快速幂

来源:互联网 发布:国家网络空间安全学院 编辑:程序博客网 时间:2024/06/04 18:35
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 06 10 2
Sample Output
060
写出几项可以发现,a,b的幂次都满足斐波那契数列,但是要注意对应关系,并且求取的过程要用到矩阵快速幂,不然会T。
由斐波那契数列递推式,F(n)=F(n-1)+F(n-2)
可以得到用来计算幂次的矩阵为
1 1
1 0
最后要注意在计算中要先初始化一个单位矩阵,并且最后讨论map[0][1](A的幂次)与map[0][0](B的幂次)是否相对应
并且取余的过程要注意,如果对1e9+7取余的话(由费马小定理),会出现错误
#include<stdio.h>#include<string.h>#define mod1  1000000007#define mod2  1000000006  struct martix{long long map[2][2];};martix mul(martix a,martix b){martix ans;ans.map[0][0]=ans.map[1][1]=ans.map[0][1]=ans.map[1][0]=0;for(int i=0;i<2;i++){for(int j=0;j<2;j++){for(int k=0;k<2;k++){ans.map[i][j]=(ans.map[i][j]+(a.map[i][k]*b.map[k][j])%mod2)%mod2;}}}return ans;}martix Quick_pow(martix a,long long b){martix ans;ans.map[0][0]=ans.map[1][1]=1;ans.map[0][1]=ans.map[1][0]=0;while(b){if(b&1)ans=mul(ans,a);b >>= 1;a=mul(a,a);}return ans;}long long quick_pow(long long a,long long b){long long ans=1;while(b>0){if(b&1)ans=(ans*a)%mod1;a=(a*a)%mod1;b>>=1;;}return ans;}int main(){long long a,b,n,answer,tmp1,tmp2;martix temp,A;temp.map[0][0]=temp.map[0][1]=temp.map[1][0]=1;temp.map[1][1]=0;while(~scanf("%lld%lld%lld",&a,&b,&n)){if(n==0){printf("%lld\n",a);continue;}A=Quick_pow(temp,n-1);/*for(int i=0;i<2;i++){for(int j=0;j<2;j++)printf("%lld ",A.map[i][j]);printf("\n");}*/tmp1=quick_pow(a,A.map[0][1]);tmp2=quick_pow(b,A.map[0][0]);answer=(tmp1*tmp2)%mod1;printf("%lld\n",answer);}}


阅读全文
0 0
原创粉丝点击