斐波那契数列的Log(n)解法
题目大意
题目中定义了一个新的
Super Fibonacci
数列.
给定一个N, 我们计算数列的第N个值是多少.
题目中的N是很大的, 有64位int
的大小, 每增加一项, 需要5个乘法, 5个加法.
挨个计算是一定会超时的. 但是有什么更简单的方法呢?
普通Fibonacci
的计算
读完题目, 我就在想普通Fibonacci
数列的计算, 因为之前有了解过Log(n)的计算方法,
是通过矩阵进行快速幂的方式进行.
方法大概是这样的:
如果我们简单Fibonacci
的计算带入到公式里.
$$ \times
$$
这里的M就是
而, 就可以转换成下列等式 , 只要求解出, 就能得到计算结果.
这样的方法, 求出M数组就很重要了?
如何求解关键的M数组
这里我提供一种简单的思路. 针对Super Fibonacci
. 我们可以这样设置: 首先这个M数组
一定是一个的矩阵, 而后, 我们可以假设的第一行是这样的.
那么的第一行就应该是这样的.
别问我为什么是这样, 假如不是这样, 你怎么进行迭代. 有了上述假设, 我们把其他行 全部填0.
根据两个数组的第一行, 我想能够推导出来M数组(根据逆推法, 计算一下矩阵的乘法):
对于任意的n, 我们可以先求出, 就可以获得最终结果.
矩阵快速幂的使用
这是一个简答的快速幂求解方案, 求解, 下方的 Java代码来自快速幂
1 | private static int cifang(int a, int b) { |
对于我们来说, 快速幂是针对矩阵来做的.
1 | unsigned long long orig_m_mtx[][5] = { |
详细代码见gist.
扩展方法(O(1))
学过线性代数的话, 可能能够看懂以下的解法 The Linear Algebra View of the Fibonacci Sequence, 这个解法可以直接求出通项. 但是计算量不小, 哈哈.