2020牛客寒假算法基础集训营1 J - u's的影响力 (矩阵快速幂,欧拉降幂)
显然x,y,a的幂次满足递推式:(假设n 从0开始)
f[n] = f[n-1] + f[n-2] ,f[0] = 1,f[1] = 0;//x
f[n] = f[n-1] + f[n-2] ,f[0] = 0,f[1] = 1;//y
f[n] = f[n-1] + f[n-2] + b , f[0] = 0,f[1] = 0;//a
然后矩阵快速幂求出来x,y,a的幂次,求的时候使用欧拉降幂公式降幂。
两个需要注意的点就是,x^0 和 0^x 的问题,这两种情况在涉及快速幂的时候记得特判一下。
#define mod 1000000007
struct matrix
{
ll x[3][3];
matrix(){memset(x,0,sizeof(x));}
};
matrix multi(matrix a,matrix b,int up)//矩阵相乘
{
matrix temp;
for(int i=0;i<up;i++)
for(int j=0;j<up;j++)
for(int k=0;k<up;k++)
{
temp.x[i][j]+=(a.x[i][k]*b.x[k][j]%(mod-1));
temp.x[i][j]%=(mod-1);//
}
return temp;
}
matrix quick_multi(matrix a,ll n,int up)//矩阵快速幂
{
matrix temp=a;
n--;
while(n)
{
if(n&1) temp=multi(temp,a,up);
a=multi(a,a,up);
n>>=1;
}
return temp;
}
ll qpow(ll a,ll b)//a^b
{
if(b==0) return 1;
a%=mod;
ll ans=1,temp=a;
while(b)
{
if(b&1) ans=(ans*temp)%mod;
temp=(temp*temp)%mod;
b>>=1;
}
return ans%mod;
}
int main()
{
ll n,x,y,a,b; cin>>n>>x>>y>>a>>b;
--n;
if(n==0) cout<<x%mod<<endl;
else if(n==1) cout<<y%mod<<endl;
else if (x%mod==0 || y%mod==0 || a%mod==0) cout<<0<<endl;
else
{
matrix ans;
ans.x[0][0]=ans.x[0][1]=ans.x[1][0]=1;
ans = quick_multi(ans,n-1,2);
matrix tmp,tmp2;
//x
tmp.x[1][0] = 1;tmp= multi(ans,tmp,2);
//y
tmp2.x[0][0] = 1;tmp2= multi(ans,tmp2,2);
//a的幂
memset(ans.x,0,sizeof(ans.x));
ans.x[0][0]=ans.x[0][1]=ans.x[0][2]=ans.x[1][0]=ans.x[2][2] =1;
ans=quick_multi(ans,n-2,3);
matrix tmp3;
tmp3.x[0][0] = tmp3.x[2][0] = b%(mod-1);
tmp3=multi(ans,tmp3,3);
//快速幂计算
ll res = qpow(x,tmp.x[0][0]%(mod-1));
res = res*((qpow(y,tmp2.x[0][0]))%mod)%mod;
res = res*((qpow(a,tmp3.x[0][0]))%mod)%mod;
cout<<res<<endl;
}
return 0;
}