HDU 4549 M斐波那契數列
阿新 • • 發佈:2019-02-14
HDU 4549 M斐波那契數列
M斐波那契數列F[n]是一種整數數列,它的定義如下:
題意:
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
給出a, b, n,求出F[n]對1000000007取模後的值.
分析:
通過代數計算F[n]前幾項,
F[2]=a*b; F[3]=a*b^2;
F[4]=(a^2)*(b^3) F[5]=(a^3)*(b^5).
......
可以得到F[n]=a^f(n-1)*b^f(n) .其中f(n)是斐波那契數列(0,1,1,2,3,5,8....)
所以問題轉化為快速求出斐波那契數列(n很大)
注:( a^ f(n-1) )%1000000007 是不等於 a^(f(n-1)%1000000007 )
(因為這個WA了6發,一直覺得沒錯)
f(n-1)是個很大的數,不能直接求出來再mod。
此時要用到費馬小定理:假如p是質數,且Gcd(a,p)=1,那麼 a(p-1) ≡1(mod p)。
即是a^f(n-1)%1000000007=a^( f (n - 1 ) %1000000006 )%1000000007
所以利用矩陣快速求出f(n-1)mod1000000006 基本就可以解決了。
/*////////////////////////////// //////////////////////////////*/ #include <cstdio> #include <cstring> #include <cmath> #include <iostream> using namespace std; typedef long long LL; int n,mod=1000000007; struct Matrix { LL m[2][2]; void clear() { memset(m,0,sizeof(m)); } }E, Z; Matrix Mut(Matrix A, Matrix B) { Matrix ans; for (int i = 0; i<2; i++) for (int j = 0; j<2; j++) { ans.m[i][j] = 0; for (int k = 0; k<2; k++) { ans.m[i][j] += ((A.m[i][k])*(B.m[k][j])); ans.m[i][j]%=(mod-1); // mod 1000000006 } } return ans; } Matrix Pow(Matrix A, int b) { Matrix t = A, ans = E; while (b) { if (b % 2) ans = Mut(ans, t); b /= 2; t = Mut(t, t); } return ans; } LL P(LL a, LL b) { if(b==0) return 1; LL x=P(a,b/2); LL ans=(long long )x*x%mod; if(b%2) ans=ans*a%mod; return ans; } int main() { // freopen("in.txt", "r", stdin); Matrix A; LL a,b; while(cin>>a>>b>>n) { if(n==0) cout<<a<<endl; else if(n==1) cout<<b<<endl; else { LL t1,t2; A.m[0][0]=1;A.m[0][1]=1; A.m[1][0]=1;A.m[1][1]=0; E=A; Matrix ans=Pow(A,n-2); // t1 : f(n-1) t2: f(n) t1=ans.m[0][1]; t2=ans.m[0][0]; LL t=(P(a,t1)*P(b,t2))%mod; cout<<t<<endl; } } return 0; }