题目
思路
首先可以很容易的发现
\(f(n)=a^x*b^y\)
之后我们根据函数的定义单独考虑\(f(n)\)是a的多少次幂乘上b的多少次幂
然后我们很容易的发现,
\(f(n)\)这个函数其实就是对指数进行了\(g_n=g_{n-1}+g_{n-2}\)
也就是斐波拉契数列
之后可以自然而然地想到矩阵的优化
但是这里要注意,虽然a和b的加速矩阵是一样的
但是他们的初始矩阵却是不一样的
因为\(f(0)==a\)与\(f(1)==b\)的情况
另外当mod是质数的时候,\(\varphi(mod)=mod-1\),
而且进行矩阵快速幂的时候的模数与最后算答案的模数是不一样的
代码
#include<iostream>
#include<cstring>
using namespace std;
const long long mod=1e9+6;
const long long modd=1e9+7;
struct mat
{
long long n;
long long m;
long long a[5][5];
mat()
{
n=0;
m=0;
memset(a,0,sizeof(a));
}
friend mat operator * (const mat &a,const mat &b)
{
mat t;
t.n=a.n;
t.m=b.m;
for(int i=1;i<=a.n;i++)
{
for(int j=1;j<=b.m;j++)
{
for(int k=1;k<=a.m;k++)
{
t.a[i][j]=(t.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
}
}
}
return t;
}
};
long long varphi(long long n)
{
long long ans=n;
for(int i=2;1ll*i*i<=n;i++)
{
if(n%i==0)
{
ans=ans/i*(i-1);
while(!(n%i))
n/=i;
}
}
if(n>1)
ans=ans/n*(n-1);
return ans;
}
mat qkpow(mat a,long long b)
{
if(b==1)
return a;
mat t=qkpow(a,b/2);
t=(t*t);
if(b%2==1)
t=(t*a);
return t;
}
long long qkpow(long long a,long long b)
{
if(b==0)
return 1;
if(b==1)
return a;
long long t=qkpow(a,b/2);
t=(t*t)%modd;
if(b%2==1)
t=(t*a)%modd;
return t;
}
long long a,b,n;
mat t1;
mat t2;
mat acc;
void init()
{
acc.n=acc.m=4;
acc.a[1][2]=acc.a[2][1]=acc.a[2][2]=1;
acc.a[1][1]=0;
}
int main()
{
while(cin>>a>>b>>n)
{
if(n==0)
{
cout<<a<<'\n';
continue;
}
if(n==1)
{
cout<<b<<'\n';
continue;
}
t1.n=t2.n=1;
t1.m=t2.m=2;
t1.a[1][1]=t2.a[1][2]=1;
t1.a[1][2]=t2.a[1][1]=0;
init();
t1=t1*qkpow(acc,n-1);
init();
t2=t2*qkpow(acc,n-1);
//cout<<t1.a[1][2]<<' '<<t2.a[1][2]<<'\n';
cout<<qkpow(a%modd,t1.a[1][2])*qkpow(b%modd,t2.a[1][2])%modd<<'\n';
}
return 0;
}