斐波那契數列——矩陣的冪求解
阿新 • • 發佈:2019-02-01
題目:
斐波那契數列的遞推公式如下:
F(0) = 0;
F(1) = 1;
F(n + 2) = F(n + 1) + F(n);
求數列的第N項的值對10000取餘的結果。( 0<=n<= 10^16)
求解斐波那契數列,如果N比較小的情況下,可以直接打表求解,但是對於N很大的情況下,並不適用。
所以,有些人會想到高精度計算,但是,N達到10^5以上時,時間複雜度難以想象,每計算一個數,需要進行高精度加法。然而還有求解對10000的取餘的值。
我們可以用矩陣的冪來求解。斐波那契數列的遞推公式為F(n + 2) = F(n + 1) + F(n);可以轉換為矩陣的形式
將這公式乘開,還是等於上面的遞推公式。因此,得到了F(n)的求解公式
下面的是程式碼:
#include <iostream> #include <vector> using namespace std; typedef vector<int> vec; typedef vector<vec> mat; typedef __int64 ll; const int M = 10000; mat mul(mat &A, mat &B) //矩陣相乘函式 { mat C(A.size(), vec(B.size())); //二維陣列 for(int i = 0; i < A.size(); i++) for(int k = 0; k < B.size(); k++) for(int j = 0; j < B.size(); j++) C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % M; return C; } mat pows(mat A, ll n) //快速冪運算 { mat B(A.size(), vec(A.size())); //二維陣列 for(int i = 0; i < A.size(); i++) B[i][i] = 1; while(n > 0) { if(n & 1) B = mul(B, A); A = mul(A, A); n >>= 1; } return B; } int main() { ll n; while(scanf("%I64d", &n) != EOF) //輸入n { mat A(2, vec(2)); A[0][0] = 1; A[0][1] = 1; A[1][0] = 1; A[1][1] = 0; A = pows(A, n); printf("%d\n", A[1][0]); } return 0; }