原题地址:点击打开链接
思路:
F(n)=F(n−1)^1*F(n−2)^1
F(n)=F(n−2)^2*F(n−3)^1
F(n)=F(n−3)^3*F(n−4)^2
F(n)=F(n−4)^5*F(n−5)^3
。。。
F(n)=F(1)^f(n)*F(0)^f(n−1)
F(n)=b^f(n)*a^f(n−1)
可以看出f(n)就是斐波那契数列的第n项,这里我们只需要找出f(n)和f(n-1)就可以求出F(n)的值。
但是要注意我们这里得出的f(n)和f(n-1)都是取余过后的,直接计算F(n)=b^f(n)+a^f(n-1)次是错的。
这里我们用到了一个费马定理。(x^n)%p=x^(n%(p-1))%p,p要求是素数,因为MOD=1000000007是素数,所以可用此定理。
代码
#include<stdio.h>
#include<string.h>
#define MOD 1000000007
long long a,b,n;
struct Matrix
{
long long a[3][3];
Matrix operator *(Matrix mt)
{
int i,j,k;
Matrix res;
for(i=1;i<=2;i++)
for(j=1;j<=2;j++)
res.a[i][j]=0;
for(i=1;i<=2;i++)
for(j=1;j<=2;j++)
for(k=1;k<=2;k++)
{
res.a[i][j]=(res.a[i][j]+a[i][k] * mt.a[k][j] ) % (MOD-1);
}
return res;
}
}m,res;
long long fp(long long x,long long n)
{
long long r=1;
while(n>0)
{
if(n&1)
{
r=(r*x)%MOD;
}
n=n>>1;
x=(x*x)%MOD;
}
return r;
}
long long solve(long long n)
{
long long x,y;
long long g,h;
m.a[1][1]=1;m.a[1][2]=1;m.a[2][1]=1;m.a[2][2]=0;
res.a[1][1]=1;res.a[1][2]=0;res.a[2][1]=0;res.a[2][2]=1;
while(n>0)
{
if(n&1)
{
res=res*m;
}
n=n>>1;
m=m*m;
}
x=(res.a[1][1]+res.a[1][2])%(MOD-1);
y=(res.a[2][1]+res.a[2][2])%(MOD-1);
g=fp(b,x);
h=fp(a,y);
return (g*h)%MOD;
}
int main()
{
while(scanf("%lld%lld%lld",&a,&b,&n)!=EOF)
{
if(n==0)
printf("%lld\n",a);
else if(n==1)
printf("%lld\n",b);
else if(n==2)
printf("%lld\n",(a*b)%MOD);
else
{
long long res=solve(n-2);
printf("%lld\n",res);
}
}
return 0;
}