Brute-force Algorithm(矩阵快速幂&欧拉降幂)

Brute-force Algorithm(矩阵快速幂&欧拉降幂)


题意

a , b , a b , a b 2 … a,b,ab,ab^2\dots a,b,ab,ab2 序列的 a , b a,b a,b指数是斐波那契形式,求在模 p p p意义下的第 n n n项。


思路

考虑先用矩阵快速幂预处理出 a , b a,b a,b的指数,因为指数非常大,考虑欧拉降幂,只需要矩阵乘法中间加个特判即可。

时间复杂度: O ( p + T l o g n ) O(p+Tlogn) O(p+Tlogn)


代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
#define mst(a) memset(a,0,sizeof a)
int phi[N],p[N],cnt;
bitset<N>vis;
void ss(int n){
    phi[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i]) p[++cnt]=i,phi[i]=i-1;
        for(int j=1;j<=cnt&&i*p[j]<=n;j++){
            vis[i*p[j]]=1;
            if(i%p[j]==0){
                phi[i*p[j]]=phi[i]*p[j];
                break;
            }phi[i*p[j]]=phi[i]*phi[p[j]];
        }
    }
}
ll mod;
struct Mat{
	ll a[3][3];
	Mat operator * (const Mat & mat)const{ //重载乘号 
		Mat ans;
		memset(ans.a,0,sizeof ans.a);//初始化 
		for(int i=1;i<=2;i++)
			for(int j=1;j<=2;j++)
				for(int k=1;k<=2;k++){
					ans.a[i][j]=(ans.a[i][j]+a[i][k]*mat.a[k][j]);
					//欧拉降幂 
					if(ans.a[i][j]>phi[mod]) ans.a[i][j]=ans.a[i][j]%phi[mod]+phi[mod];
				}
		return ans; 
	}
}m;
Mat ksm(Mat m,ll x){ //矩阵快速幂板子 
	 Mat ans;
	 memset(ans.a,0,sizeof ans.a); 
	 ans.a[1][1]=ans.a[2][2]=1; 
	 while(x){
	 	 if(x&1) ans=ans*m;
	 	 m=m*m;
	 	 x>>=1;
	 }
	 return ans;
}
ll ksm(ll a,ll n,ll m){
	ll ans=1;
	while(n){
		if(n&1) ans=ans*a%m;
		a=a*a%m;
		n>>=1;
	}
	return ans;
}
int main(){
	m.a[1][1]=m.a[1][2]=m.a[2][1]=1;
	ss(N-5); 
	int T;scanf("%d",&T);
	int kase=0;
	while(T--){
	ll a,b,n;scanf("%lld%lld%lld%lld",&a,&b,&mod,&n);
	printf("Case #%d: ",++kase);
	if(n==1){
		printf("%lld\n",a%mod);
	}
	else if(n==2) printf("%lld\n",b%mod);
	else {
	m.a[1][1]=m.a[1][2]=m.a[2][1]=1,m.a[2][2]=0;
	m=ksm(m,n-2);
	printf("%lld\n",ksm(b,m.a[1][1],mod)*ksm(a,m.a[1][2],mod)%mod);
	}
		}
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷酷的Herio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值