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]的值吗?
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
0 1 0 6 10 2
0 60
写出几项可以发现,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); } }