矩阵快速幂求斐波那契数列

#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
#define si(x) scanf("%d",&x)
#define sl(x) scanf("%lld",&x)
#define lc (d<<1)
#define rc (d<<1|1)
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=1e6+8;
typedef long long LL;
typedef unsigned long long ULL;
LL mod=1e9+7;
const ULL base=1e7+7;
using namespace std;
int dp[maxn];
int di[3];
LL m;
struct maxt{
    LL s[3][3];
    int ii,jj;
}t,x;
maxt MUL(maxt a,maxt b){
    int kk=a.jj;
    maxt ans;
    ans.ii=a.ii;
    ans.jj=b.jj;
    for(int i=1;i<=a.ii;i++){
        for(int j=1;j<=b.jj;j++){
            ans.s[i][j]=0;
            for(int k=1;k<=kk;k++){
                ans.s[i][j]+=a.s[i][k]*b.s[k][j];
            }
            ans.s[i][j]%=mod;
        }
    }
    return ans;
}
maxt mqpow(maxt x,LL u){
    maxt ans;
    ans.ii=x.ii;
    ans.jj=x.jj;
    for(int i=1;i<=ans.ii;i++){
        for(int j=1;j<=ans.jj;j++){
            if(i==j){
                ans.s[i][j]=1;
            }
            else{
                ans.s[i][j]=0;
            }
        }
    }
    while(u){
        if(u&1){
            ans=MUL(ans,x);
        }
        x=MUL(x,x);
        u>>=1;
    }
    return ans;
}
LL qpow(LL a,LL b){
    LL ans=1;
    while(b){
        if(b&1){
            ans=ans*a%m;
        }
        a=a*a%m;
        b>>=1;
    }
    return ans;
}
LL getf(LL a){
    maxt now,kk;
    now.ii=now.jj=2;
    for(int i=1;i<=2;i++){
        for(int j=1;j<=2;j++){
            now.s[i][j]=1;
        }
    }
    now.s[1][1]=0;
    kk.s[1][1]=0;
    kk.ii=1;kk.jj=2;
    kk.s[1][1]=1;
    kk.s[2][1]=1;
    now=mqpow(now,a-1);
    kk=MUL(now,kk);
    return kk.s[1][1];
}
LL euler_Phi(LL n){
    LL m=(LL)sqrt(n+0.5);
    LL ans=n;
    for(LL i=2;i<=m;i++){
        if(n%i==0){
            ans=ans/i*(i-1);
            while(n%i==0) n/=i;
        }
    }
    if(n>1) ans=ans/n*(n-1);
    return ans;
}
int main(){
    fio;
    LL a,b,c,d,n,ans;
    /*cout<<getf(1)<<' '<<getf(2)<<' '<<getf(3)<<' '<<getf(4)<<endl;
    for(LL i=5;i<=10;i++){
        cout<<getf(i)<<endl;
    }*/
    while(cin>>a>>b>>c>>d>>m>>n){
        mod=euler_Phi(m);
        if(n==1) ans=a%m;
        else if(n==2) ans=a*b%m;
        else{
            LL k=getf(n);
            //cout<<k<<endl;
            if(k<0) k+=mod;
            k+=mod;
            ans=qpow(a%m,k);
            ans%=m;
            k=getf(n+1)-1;
            //cout<<k<<endl;
            if(k<0) k+=mod;
            k+=mod;
            ans*=qpow(b%m,k);
            ans%=m;
            k=(getf(n+2)-n-1)*d;
            //cout<<k<<endl;
            k%=mod;
            if(k<0) k+=mod;
            k+=mod;
            ans*=qpow(c%m,k);
            ans%=m;
        }
        int qw=0;
        LL zz=ans;
        while(zz) qw++,zz/=10;
        for(int i=1;i<=9-qw;i++) cout<<0;
        cout<<ans<<endl;
    }
}

猜你喜欢

转载自www.cnblogs.com/Profish/p/10453122.html