注意n==1或n==2时最好特判一下。
观察递推式我们可以发现,所有的fi都是a的幂次,所以我们可以对fi取一个以a为底的log,即gi=loga fi
那么递推式变成gi=b+c∗gi−1+gi−2,这个式子可以矩阵乘法
但要注意a^b%c!=a^(b%c)%c,而是a^b%c=a^(b%phi(c))%c;
由于c为质数,所以phi(c)==c-1;
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
ll a,b,c,n,p;
mat mul(mat a,mat b)
{
if (a[0].size()!=b.size())
swap(a,b);
int len1=a.size(),len2=b[0].size(),len3=b.size();
mat c(len3,vec(len3));
for (int i=0;i<len1;i++)
for (int j=0;j<len2;j++)
for (int k=0;k<len3;k++)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%(p-1);
return c;
}
mat mpow(mat a,ll n)
{
int len=a.size();
mat b(len,vec(len));
for (int i=0;i<len;i++)
b[i][i]=1;
while(n)
{
if (n&1)
b=mul(b,a);
n>>=1;
a=mul(a,a);
}
return b;
}
ll pow(ll a,ll n)
{
ll ans=1;
while(n)
{
if (n&1)
ans=(ans*a)%p;
n>>=1;
a=(a*a)%p;
}
return ans;
}
mat ma(1,vec(3)),mb(3,vec(3)),mc;
int main()
{
ll t;
cin>>t;
while(t--)
{
cin>>n>>a>>b>>c>>p;
ma[0][1]=ma[0][2]=1;
mb[0][1]=mb[1][0]=mb[2][1]=mb[2][2]=1;
mb[1][1]=c;
mc=mpow(mb,n-1);
mc=mul(ma,mc);
a=pow(a,b);
a=pow(a,mc[0][0]);
cout<<a<<endl;
}
}#include<iostream>
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
ll a,b,c,n,p;
mat mul(mat a,mat b)
{
if (a[0].size()!=b.size())
swap(a,b);
int len1=a.size(),len2=b[0].size(),len3=b.size();
mat c(len3,vec(len3));
for (int i=0;i<len1;i++)
for (int j=0;j<len2;j++)
for (int k=0;k<len3;k++)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%(p-1);
return c;
}
mat mpow(mat a,ll n)
{
int len=a.size();
mat b(len,vec(len));
for (int i=0;i<len;i++)
b[i][i]=1;
while(n)
{
if (n&1)
b=mul(b,a);
n>>=1;
a=mul(a,a);
}
return b;
}
ll pow(ll a,ll n)
{
ll ans=1;
while(n)
{
if (n&1)
ans=(ans*a)%p;
n>>=1;
a=(a*a)%p;
}
return ans;
}
mat ma(1,vec(3)),mb(3,vec(3)),mc;
int main()
{
ll t;
cin>>t;
while(t--)
{
cin>>n>>a>>b>>c>>p;
ma[0][1]=ma[0][2]=1;
mb[0][1]=mb[1][0]=mb[2][1]=mb[2][2]=1;
mb[1][1]=c;
mc=mpow(mb,n-1);
mc=mul(ma,mc);
a=pow(a,b);
a=pow(a,mc[0][0]);
cout<<a<<endl;
}
}