二分法求解超大項的斐波那契數列數值
阿新 • • 發佈:2019-02-19
我們將數列寫成:
Fibonacci[0] = 0,Fibonacci[1] = 1
Fibonacci[n] = Fibonacci[n-1] + Fibonacci[n-2] (n >= 2)
可以將它寫成矩陣乘法形式:
將右邊連續的展開就得到:
下面就是要用O(log(n))的演算法計算:
程式碼如下:
/* 求解任一項斐波那契數列值,輸入要計算的某一項n,輸出該項對應的斐波那契數列值 由於值超大,結果對1000000007取餘 */ #include<iostream> #include<cstdio> using namespace std; struct Matrix { __int64 a[2][2]; }; Matrix E; void InitE(int size) //初始化單位矩陣 { for(int i=0;i<size;i++) { for(int j=0;j<size;j++) E.a[i][j]=(i==j); } } Matrix MatrixMul(Matrix a,Matrix b) //兩矩陣相乘 { Matrix c; int i,j,k; for(i=0;i<2;i++) { for(j=0;j<2;j++) { c.a[i][j]=0; for(k=0;k<2;k++) { c.a[i][j] += ((a.a[i][k]%1000000007)*(b.a[k][j]%1000000007)); c.a[i][j]%=1000000007; } } } return c; } Matrix MatrixPow(Matrix a,__int64 n) //矩陣快速二分求n次冪 { Matrix t=E; while(n>0) { if(1&n) //n是奇數 t=MatrixMul(t,a); a=MatrixMul(a,a); n >>= 1; } return t; } int main(void) { __int64 n; Matrix matrix,m; InitE(2); while(scanf("%I64d",&n)!=EOF) { if(n==1||n==2) printf("1\n"); else { matrix.a[0][0]=1; //構造初始矩陣 matrix.a[0][1]=1; matrix.a[1][0]=1; matrix.a[1][1]=0; m=MatrixPow(matrix,n-1); printf("%d\n",(m.a[0][0])%1000000007); } } return 0; }
截圖如下: