标签:des style blog http io ar color os sp
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1609 Accepted Submission(s): 460
F(n)=F(n-1)*F(n-2)
F(1)=a;
F(2)=b;
F(3)=a^1*b^1
F(4)=a^1*b^2
F(5)=a^2*b^3
F(6)=a^3*b^5
F(n)=a^f(n‘-1)*b^f(n‘) f(n‘)为斐波拉契数列
这样就可以先算出F(n)对应f(n‘)、f(n‘-1),再二分快速幂,F(n)=a^f(n‘-1)%MOD * b^f(n‘)%MOD
另外由于n比较大且MOD为质数,则根据费马小定理得:F(n)=a^(f(n‘-1)%(MOD-1)%MOD) * b^(f(n‘)%(MOD-1))%MOD
注意这里n‘和n不一样,当n为3时,f(n‘)=1,不妨让n‘=n-2...
#include <iostream> #include <cstdio> using namespace std; #define MOD 1000000007 #define ll __int64 #define N 2 ll quickadd(ll a,ll b) //矩阵快速加,防溢出,其实可以不用这个 { ll ret=0; while(b) { if(b&1) { ret+=a; if(ret>=MOD) ret-=MOD; } a<<=1; if(a>=MOD) a-=MOD; b>>=1; } return ret; } ll quickpow(ll a,ll b) //矩阵快速幂 { ll ret=1; while(b) { if (b&1) ret=quickadd(a,ret); a=quickadd(a,a); b>>=1; } return ret; } void mul(ll a[N][N],ll b[N][N]) //矩阵相乘 { ll i,j,k; ll c[N][N]={0}; for(i=0;i<N;i++) { for(j=0;j<N;j++) { for(k=0;k<N;k++) { c[i][j]=(c[i][j]+a[i][k]*b[k][j])%(MOD-1); } } } for(i=0;i<N;i++) { for(j=0;j<N;j++) { a[i][j]=c[i][j]; } } } int main() { ll A,B,n; while(scanf("%I64d%I64d%I64d",&A,&B,&n)!=EOF) { if(n==0) printf("%I64d\n",A%MOD); else if(n==1) printf("%I64d\n",B%MOD); //特判0,1 else { n-=2; ll a[N][N]={1,1},b[N][N]={0,1,1,1}; while(n) { if(n&1)mul(a,b); mul(b,b); n>>=1; } ll k1=a[0][0]; ll k2=a[0][1]; ll ans=1; ans=ans*quickpow(A,k1)%MOD; ans=ans*quickpow(B,k2)%MOD; printf("%I64d\n",ans); } } return 0; }
标签:des style blog http io ar color os sp
原文地址:http://www.cnblogs.com/hate13/p/4123617.html