一、题目
二、解法
可以把这个变形的斐波那契理解为指数上的正常斐波那契,分别做两次矩阵加速,第一次初始值为
1
,
0
1,0
1,0,第二次初始值为
0
,
1
0,1
0,1,把两次的
a
F
(
n
)
,
b
F
(
n
)
a^{F(n)},b^{F(n)}
aF(n),bF(n)求乘积即可。
现在的问题是
F
(
n
)
F(n)
F(n)太大会爆,考虑到模数是一个质数
1
e
9
+
7
1e9+7
1e9+7,利用欧拉定理
a
φ
(
n
)
=
1
a^{\varphi(n)}=1
aφ(n)=1,对指数直接取模
1
e
9
+
6
1e9+6
1e9+6即可,最后再算快速幂,取模
1
e
9
+
7
1e9+7
1e9+7。
#include <cstdio>
#include <cstring>
#define int long long
const int MOD = 1e9+7;
const int phi = 1e9+6;
int read()
{
int x=0,flag=1;
char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
struct Matrix
{
int n,m,a[3][3];
Matrix() {n=m=0;memset(a,0,sizeof a);}
Matrix operator * (const Matrix &B) const
{
Matrix res;
res.n=n;res.m=B.m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=B.m;k++)
res.a[i][k]=(res.a[i][k]+a[i][j]*B.a[j][k])%phi;
return res;
}
}F,A;
Matrix Mpow(Matrix a,int b)
{
Matrix res;
res.n=a.n;res.m=a.m;
for(int i=1;i<=res.n;i++)
res.a[i][i]=1;
while(b>0)
{
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int qkpow(int a,int b)
{
int res=1;
while(b>0)
{
if(b&1) res=res*a%MOD;
a=a*a%MOD;
b>>=1;
}
return res;
}
int a,b,n,ans;
signed main()
{
while(~scanf("%d %d %d",&a,&b,&n))
{
if(n<2)
{
if(n==0) printf("%d\n",a);
else printf("%d\n",b);
continue;
}
F.n=1;F.m=2;A.n=2;A.m=2;
A.a[1][1]=A.a[1][2]=A.a[2][1]=1;
F.a[1][2]=1;
F.a[1][1]=0;
ans=qkpow(a,(F*Mpow(A,n-1)).a[1][1]);
F.a[1][1]=1;
F.a[1][2]=0;
ans=ans*qkpow(b,(F*Mpow(A,n-1)).a[1][1])%MOD;
printf("%d\n",ans);
}
}