题目:F(0) = 0, F(1) = 1, F(n+2) = F(n+1) + F(n),且0<=n <= 10^16,求第n项的值。

分析:通常情况下,我们求第n项的斐波那契数是根据递推式进行递归求解,适当优化后时间复杂度为O(n)。但如果n的规模非常大时,原有算法效率显得太低。在这里给大家介绍一种比较高效的即用矩阵求解。

由递推式:F(n+1) = F(n) + F(n-1), F(n) = F(n) + 0*F(n-1)

可得如下矩阵关系(系数矩阵与变量矩阵的乘积):

(F(n+1), F(n))= ((1, 1), (1, 0)) * (F(n), F(n-1))

进一步可得:

(F(n+1), F(n)) = ((1, 1), (1, 0))^n * (f1, f0)

令A=((1, 1), (1, 0)),A^n可以通过矩阵的快速幂求解,时间复杂度为logn。

由于a*m的矩阵与m*b的矩阵相乘,时间复杂度为O(abm),故本例中总共的时间复杂度为O(8logn)。

顺带提及一下单位矩阵I的概念:主对角线为1的矩阵为单位矩阵,对于任意可做乘积的矩阵A有I*A = A。

核心代码:

mat pow(mat A, int n)//求矩阵A的n次方

{

  mat B(A.size(), vec(A[0].size()));

  for(int i = 0; i < A.size(); ++i)

    B[i][i] = 1;

  while(n > 0)

  {

    if(n & 1)

      B = mult(B, A);//mult()两矩阵的乘积

    A = mult(A, A);

    n >>= 1;

  }

}