poj3070 Fibonacci 斐波那契数列的第n项的矩阵求法
对于满足(F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2)的斐波那契数列,第n项可由矩阵求出公式如下:
1 ///2014.2.24 2 ///poj3070 3 4 #include <iostream> 5 #include <vector> 6 #include <cstdio> 7 using namespace std; 8 9 #define MOD 10000 10 //定义二阶矩阵 11 struct MATRIX 12 { 13 long long f11; 14 long long f12; 15 long long f21; 16 long long f22; 17 }; 18 19 //定义二阶矩阵乘法函数 20 MATRIX matMulti(MATRIX mat1, MATRIX mat2) 21 { 22 MATRIX matrix; 23 matrix.f11 = (mat1.f11*mat2.f11 + mat1.f12*mat2.f21)%MOD; 24 matrix.f12 = (mat1.f11*mat2.f12 + mat1.f12*mat2.f22)%MOD; 25 matrix.f21 = (mat1.f21*mat2.f11 + mat1.f22*mat2.f21)%MOD; 26 matrix.f22 = (mat1.f21*mat2.f12 + mat1.f22*mat2.f22)%MOD; 27 28 return matrix; 29 } 30 31 MATRIX Fibo(int m) 32 { 33 MATRIX unitMat,retMat; 34 unitMat.f11 = (long long)1; 35 unitMat.f12 = (long long)1; 36 unitMat.f21 = (long long)1; 37 unitMat.f22 = (long long)0; 38 39 if(m==1) 40 { 41 retMat.f11 = (long long)1; 42 retMat.f12 = (long long)1; 43 retMat.f21 = (long long)1; 44 retMat.f22 = (long long)0; 45 } 46 else if(m%2 == 0) 47 { 48 retMat = Fibo(m/2); 49 retMat = matMulti(retMat,retMat); 50 } 51 else if(m%2 == 1) 52 { 53 retMat = Fibo((m-1)/2); 54 retMat = matMulti(retMat,retMat); 55 retMat = matMulti(retMat,unitMat); 56 } 57 58 return retMat; 59 } 60 61 int main() 62 { 63 // freopen("in","r",stdin); 64 // freopen("out","w",stdout); 65 66 int m; 67 vector<int> output; 68 MATRIX retMatrix; 69 70 while( cin>>m && m!=-1) 71 { 72 if(m==0) 73 { 74 output.push_back(0); 75 } 76 else 77 { 78 retMatrix = Fibo(m); 79 output.push_back( retMatrix.f12 % 10000 ); 80 } 81 } 82 83 for(vector<int>::size_type i=0; i<output.size(); i++) 84 cout<<output[i]<<endl; 85 return 0; 86 }