E. Product Oriented Recurrence(codeforces R566 div2)

  • 矩阵快速幂+欧拉降幂

思路:
思路

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll mod=1e9+7;

ll fp(ll x,ll y){//快速幂 
	ll ret=1;
	while(y){
		if(y&1)ret=ret*x%mod;	
		x=x*x%mod;
		y/=2;
	}
	return ret;
}

int N=3;//矩阵大小 

struct matrix{
	ll t[5][5];
}rela;

ll t[5][5]={
	0,0,1,0,0,
	1,0,1,0,0,
	0,1,1,0,0,
};//f的幂关系矩阵 

ll tc[5][5]={
	1,1,0,0,0,
	1,0,1,0,0,
	1,0,0,0,0,
	2,0,0,1,0,
	2,0,0,1,1
};//c幂的关系矩阵 
//递推关系是C(n+1)=C(n)+C(n-1)+C(n-2)+2*(n+1) 

matrix mul(matrix x,matrix y){//矩阵乘 
	matrix ans;	
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++){
			ans.t[i][j]=0;
			for(int k=0;k<N;k++){
				ans.t[i][j]+=x.t[i][k]*y.t[k][j]%mod;
				ans.t[i][j]%=mod;
			}				
	}
	return ans;
}

matrix fpow(matrix x,ll y){//矩阵快速幂 
	matrix ret;
	memset(ret.t,0,sizeof(ret));
	for(int i=0;i<N;i++)ret.t[i][i]=1; 
	while(y){
		if(y&1)ret=mul(ret,x);
		x=mul(x,x);	
		y>>=1;
	}
	return ret;
}

int main(){
	ios::sync_with_stdio(false);
	ll n,c,f[3],C_mi;
	cin>>n>>f[0]>>f[1]>>f[2]>>c;
	n-=3;	
	ll ans=1;
	matrix a; 
	mod--;//欧拉(费马)降幂 
	memcpy(rela.t,t,sizeof(t));
	a=fpow(rela,n);
	mod++;
	for(int i=0;i<3;i++)//分别用不同的初始矩阵求f1,f2,f3的幂 
		ans=ans*fp(f[i],a.t[i][2])%mod;//f(n)=f(n-1)+f(n-2)+f(n-3)
	
	if(n==1)C_mi=2;
	else if(n==2)C_mi=6;
	else if(n==3)C_mi=14;
	else {
		ll init[5]={14,6,2,3,1};//Cn,Cn-1,Cn-2,n,1 
		n-=3,N=5;
		mod--;欧拉(费马)降幂,之前写错位置了..调半天bug 
		memcpy(rela.t,tc,sizeof(tc));	
		a=fpow(rela,n);
		C_mi=0;
		//之前写在这 
		for(int i=0;i<5;i++){
			C_mi+=init[i]*a.t[i][0]%mod;
			C_mi%=mod; 
		}
		mod++;	
	}	 	
	ans=ans*fp(c,C_mi)%mod;	
	cout<<ans<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值