题目:求Fibonacci数列第N项,要求时间为O(logn)
分析:有个数学公式:f(n)可以通过{1,1,1,0}这个2X2矩阵相乘得到。
n-1 | |||||
f(n) | f(n-1) | = | 1 | 1 | |
f(n-1) | f(n-1) | 1 | 0 |
知道了这个公式要实现O(logn)的算法还是很简单的。
代码:
#include <iostream>
class mat2X2i{
public:
int _m[2][2];
public:
mat2X2i()
{
_m[0][0] = _m[1][0] = _m[0][1] = 1;
_m[1][1] = 0;
}
mat2X2i(int a00, int a01, int a10, int a11)
{
_m[0][0] = a00;
_m[1][0] = a01;
_m[0][1] = a10;
_m[1][1] = a11;
}
mat2X2i operator *(const mat2X2i &m)
{
return mat2X2i(this->_m[0][0] * m._m[0][0] + this->_m[1][0] * m._m[0][1],
this->_m[0][0] * m._m[1][0] + this->_m[1][0] * m._m[1][1],
this->_m[0][1] * m._m[0][0] + this->_m[1][1] * m._m[0][1],
this->_m[0][1] * m._m[1][0] + this->_m[1][1] * m._m[1][1]);
}
};
void FibonacciLogn(int n, mat2X2i &result)
{
if (n == 1)
{
result = mat2X2i();
return;
}
int middle = n >> 1;
FibonacciLogn(middle, result);
if (n - middle * 2)
{
result = result * result * mat2X2i();
}else{
result = result * result;
}
}
void main()
{
mat2X2i res;
FibonacciLogn(45, res);
}