HDU 4549 M斐波那契數列 (費馬小定理+矩陣快速冪)
阿新 • • 發佈:2019-02-18
分析:
寫出F[n]的幾項之後發現a和b的指數和斐波那契數列有關
具體的關係是 F[n]=a^fib[n-1] * b^fib[n]
矩陣快速冪求fib 快速冪求a和b的n次冪
題目要求對F[n]%mod 這裡用到費馬小定理
即: 假如p是質數,且gcd(a,p)=1,那麼 a(p-1)≡1(mod p),即:假如a是整數,p是質數,且a,p互質(即兩者只有一個公約數1),那麼a的(p-1)次方除以p的餘數恆等於1 (來自百度百科)
也就是說 ap %mod = ap%(mod-1)%mod
證明:
設 p=k*(mod-1)+r
則ap%mod=(ak*(mod-1)* ar)%mod=ar%mod=ap%(mod-1)%mod
AC程式碼:
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <math.h> #include <bitset> #include <algorithm> #include <climits> typedef long long LL; const LL mod=1000000007; using namespace std; int n=2; struct Matrix{ LL a[2][2]; void init(){ memset(a,0,sizeof(a)); for (int i=0;i<n;i++) a[i][i]=1; } }; Matrix multiply(Matrix x,Matrix y){ Matrix temp; memset(temp.a,0,sizeof(temp.a)); for (int i=0;i<n;i++){ for (int j=0;j<n;j++){ for (int k=0;k<n;k++){ temp.a[i][j]=(temp.a[i][j]+x.a[i][k]*y.a[k][j])%(mod-1); } } } return temp; } Matrix qpow(Matrix M,LL k){ Matrix temp; temp.init(); while (k){ if (k%2) temp=multiply(temp,M); k/=2; M=multiply(M,M); } return temp; } LL Power(LL a,LL b){ LL temp=1; while (b){ if(b%2) temp=(temp*a)%mod; b/=2; a=(a*a)%mod; } return temp%mod; } int main (){ LL a,b,N; //freopen("data","r",stdin); while (scanf ("%lld%lld%lld",&a,&b,&N)!=EOF){ Matrix M; memset(M.a,0,sizeof(M.a)); M.a[0][0]=M.a[0][1]=M.a[1][0]=1; if (N==0){ printf ("%lld\n",a); continue; } if (N==1){ printf ("%lld\n",b); continue; } LL p1,p2; Matrix temp; temp=qpow(M,N-1); p1=temp.a[0][0]; p2=temp.a[1][0]; //printf ("%lld %lld\n",p1,p2); printf("%lld\n",Power(a,p2)*Power(b,p1)%mod); } return 0; }