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