u's的影響力(兩次矩陣快速冪+費馬小定理+細節)

鏈接:https://ac.nowcoder.com/acm/contest/3002/J
來源:牛客網
 

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld

題目描述

本題測試樣例已經更(jia)新(qiang)。

求f[n]=f[n-1]*f[n-2]*(a^b);

μ's在九人齊心協力下,影響力越來越大了!

已知第一天影響力爲   ,第二天影響力爲   ,從第三天開始,每一天的影響力爲前兩天影響力的乘積再乘以   的   次方。 用數學語言描述是:
設第   天的影響力爲   ,那麼   , ,對於   ,  
她們想知道第   天影響力是多少?
由於這個數可能非常大,只需要輸出其對   取模的值就可以了。

輸入描述:

一行五個正整數:  。
 

    

輸出描述:

第   天的影響力對   取模的值。

示例1

輸入

複製4 2 3 2 1

4 2 3 2 1

輸出

複製72

72

說明

f(1)=2,f(2)=3,f(3)=f(1)*f(2)*2=12,f(4)=f(2)*f(3)*2=72

備註:

1000000007是素數。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
typedef long long ll;
const int mod=1e9+7;
const int mod1=1e9+6;
struct mat1{
	ll a[2][2];
};
struct mat2{
	ll a[3][3];
};
mat1 mul(mat1 a,mat1 b){
	 mat1 ans;
	 memset(ans.a,0,sizeof(ans.a));
	 for(int i=0;i<2;i++){
	 	for(int j=0;j<2;j++){
	 		for(int k=0;k<2;k++){
	 			ans.a[i][j]=(ans.a[i][j]+(a.a[i][k]*b.a[k][j])%mod1)%mod1;
			 }
		 }
	 }
	 return ans;
}
mat2 mul(mat2 a,mat2 b){
	 mat2 ans;
	 memset(ans.a,0,sizeof(ans.a));
	 for(int i=0;i<3;i++){
	 	for(int j=0;j<3;j++){
	 		for(int k=0;k<3;k++){
	 			ans.a[i][j]=(ans.a[i][j]+(a.a[i][k]*b.a[k][j])%mod1)%mod1;
			 }
		 }
	 }
	 return ans;
}
mat1 res1,ans1;
ll ksmmat(ll n){
	memset(res1.a,0,sizeof(res1.a));
	memset(ans1.a,0,sizeof(ans1.a));
	ans1.a[0][0]=1;ans1.a[1][1]=1;
	res1.a[0][0]=1;res1.a[0][1]=1;res1.a[1][0]=1;
	while(n){
		if(n&1){
			ans1=mul(res1,ans1);
		}
		res1=mul(res1,res1);
		n>>=1;
	}
	return ans1.a[0][0];
}
ll ksmmat1(ll n){
	mat2 res,ans;
	memset(res.a,0,sizeof(res.a));
	memset(ans.a,0,sizeof(ans.a));
	ans.a[0][0]=2;ans.a[1][0]=1;ans.a[2][0]=1;
	res.a[0][0]=1;res.a[0][1]=1;res.a[0][2]=1;res.a[1][0]=1;res.a[2][2]=1;
	while(n){
		if(n&1){
			ans=mul(res,ans);
		}
		res=mul(res,res);
		n>>=1;
	}
	return ans.a[0][0];
}
ll ksm(ll a,ll b){
	a%=mod;
	ll ans=1;
	while(b){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}

int main(){
	ll n,x,y,a,b;
	cin>>n>>x>>y>>a>>b;
	x%=mod;
	y%=mod;
	if(n==1){
		cout<<x<<endl;
		return 0;
	}
	else if(n==2){
		cout<<y<<endl;
		return 0;
	}
	else if(n==3){
		ll tmp=(x*y)%mod;
		cout<<tmp*ksm(a,b)%mod<<endl;
	}
	else{
		ksmmat(n-3);
		ll k1=ksm(x,ans1.a[1][0]+ans1.a[1][1]);
		ll k2=ksm(y,ans1.a[0][0]+ans1.a[0][1]);
		ll ans=(k1*k2)%mod;
		ll ans1=ksmmat1(n-4);
        ll cc=ksm(a,b);
        cc=ksm(cc,ans1);
        printf("%lld\n",((ans*cc))%mod);
	}
	
	return 0;
} 
發佈了330 篇原創文章 · 獲贊 368 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章