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;
}

posted @ 2020-02-07 15:36  Herlo  阅读(194)  评论(0编辑  收藏  举报