题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=1000
题意:定义f(0)=a,f(1)=b,f(n)=f(n-1)*f(n-2),给你a,b,n,求出f(n)%1000000007
分析:定义(x,y),x代表a的个数,y代表b的个数。
先找规律f(0)=a (1,0)
f(1)=b; (0,1)
f(2)=ab (1,1)
f(3)=abb (1,2)
f(4)=abbab (2,3)
f(5)=abbababb (3,5)
f(6)=abbababbabbab (5,8)
......
由规律可知,f(n)=a^fibonacci(n-2)*b^fibonacci(n-1),但是n=500的时候fibonacci(500)就已经超过1e100了,又因为求的数要%1000000007,而1000000007是素数,由费马小定理可知:若p为素数,a^(p-1)≡1 (mod p)。a^b%p=(a^(k(p-1)+c))%p=(a^(k(p-1))*a^c)%p=a^c%p。所以f(n)=a^(fibonacci(n-2)%1000000006)*b^(fibonacci(n-1)%1000000006)%1000000007.
代码:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
#define MOD 1000000007
struct Matrax
{
LL mat[2][2];
}U,F;
Matrax multi(Matrax a,Matrax b)
{
Matrax ans;
int i,j,k;
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
ans.mat[i][j]=0;
for(k=0;k<2;k++)
ans.mat[i][j]=(ans.mat[i][j]+(a.mat[i][k]%(MOD-1))*(b.mat[k][j]%(MOD-1)))%(MOD-1);
}
}
return ans;
}
Matrax my_pow_matrax(int n)
{
Matrax p=F,ans=U;
while(n)
{
if(n&1)
ans=multi(ans,p);
n>>=1;
p=multi(p,p);
}
return ans;
}
void Init()
{
U.mat[0][0]=U.mat[1][1]=1;
U.mat[0][1]=U.mat[1][0]=0;
F.mat[0][0]=F.mat[0][1]=F.mat[1][0]=1;
F.mat[1][1]=0;
}
LL my_pow_ll(LL a,LL n)
{
LL ans=1ll,p=a;
while(n)
{
if(n&1)
ans=((ans%MOD)*(p%MOD))%MOD;
n>>=1;
p=((p%MOD)*(p%MOD))%MOD;
}
return ans;
}
int main()
{
Init();
LL a,b,n;
while(scanf("%lld%lld%lld",&a,&b,&n)!=EOF)
{
if(n==0)
{
printf("%lld\n",a%MOD);
continue;
}
else if(n==1)
{
printf("%lld\n",b%MOD);
continue;
}
else if(n==2)
{
printf("%lld\n",a*b%MOD);
continue;
}
else
{
Matrax temp=my_pow_matrax(n-1);
LL f1=temp.mat[0][0]*1+temp.mat[1][0]*0; // fib(n)
LL f2=temp.mat[0][1]*1+temp.mat[1][1]*0; // fib(n-1)
LL ans=(my_pow_ll(a,f2)%MOD)*(my_pow_ll(b,f1)%MOD)%MOD;
printf("%lld\n",ans);
}
}
return 0;
}