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[3]=ab,F[4]=a b 2 b^2 b2,F[5]= a 2 a^2 a2 b 3 b^3 b3 ,F[6]= a 3 a^3 a3 b 5 b^5 b5
F[n]= a f i b [ n − 1 ] a^{fib[n-1]} afib[n−1] b f i b [ n ] b^{fib[n]} bfib[n] (fib为斐波那契数列)
然后我们需要快速求出fib[n]和fib[n-1],如下图
然后就是用矩阵快速幂求
[ 1 1 1 0 ] \left[ \begin{matrix} 1 & 1\\ 1 & 0 \end{matrix} \right] [1110] 的n-1次幂
矩阵快速幂:就是普通的快速幂在乘的时候变成矩阵乘法。
因为在求矩阵的n-1次幂的时候数可能很大,根据题意要对1e9+7取余;
根据费马小定理:当p为质数时候, a^(p-1)≡1(mod p)。
因为1e9+7是质数,所以模1e9+6
一些注意的点在代码中
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
struct matrix
{
ll tt[2][2];
};
struct matrix mul(struct matrix x,struct matrix y) //矩阵乘法
{
struct matrix t1;
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
t1.tt[i][j]=0;
for(int k=0;k<2;k++){
t1.tt[i][j]=t1.tt[i][j]+x.tt[i][k]*y.tt[k][j]%(mod-1);
t1.tt[i][j]%=(mod-1); //费马小定理:a^(p-1)%p与1同余(p为素数且a与p互质)
}
}
}
return t1;
}
struct matrix fb(struct matrix a,ll n) //矩阵快速幂
{
struct matrix t;
for(int i=0;i<2;i++) //这里一定要初始化,否则t会出问题
for(int j=0;j<2;j++)
t.tt[i][j]=0;
for(int i=0;i<2;i++) //单位矩阵
t.tt[i][i]=1;
while(n)
{
if(n%2)
{
t=mul(t,a);
}
a=mul(a,a);
n>>=1;
}
return t;
}
long long qc(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b%2)
ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
int main()
{
ll a,b,n;
while(scanf("%lld%lld%lld",&a,&b,&n)!=EOF)
{
if(n==0)
printf("%lld\n",a%mod);
else if(n==1)
printf("%lld\n",b%mod);
else
{
struct matrix F,f;
f.tt[0][0]=f.tt[0][1]=f.tt[1][0]=1;
f.tt[1][1]=0;
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
F.tt[i][j]=0;
}
}
F=fb(f,n-1); //矩阵乘法求fib[n]和fib[n-1]
long long ans=0;
//printf("%d %d\n",F.tt[1][0],F.tt[0][0]);
ans=qc(a,F.tt[1][0])*qc(b,F.tt[0][0]); //快速幂
ans%=mod;
printf("%lld\n",ans);
}
}
return 0;
}