1. 程式人生 > >矩陣快速冪求斐波那契數列

矩陣快速冪求斐波那契數列

first pri names col second 數列 def truct a*

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

矩陣快速冪求斐波那契數列