【拾题杂谈】斐波那契类的矩阵快速幂
前置知识:矩阵快速幂
出门右转 【算法介绍】矩阵乘法 | 祝馀宫 喵!
例一:斐波那契前缀和
直接求斐波那契的例子已经在上面的文章中讲过了。这里直接开始讲斐波那契的前 n 项和怎么算。
求斐波那契的前 $n$ 项和对于 $m$ 取模的结果。
首先,不难给出递推式:
这个是最最基础的递推式子,我们不难想到之前说的列方程法。我们就可以写出下面的方程组。
由于要保证矩阵的特性,所以每一个方程的对应每一项的未知数都得设置成一样的,如果没有这一项,说明系数等于 0 。然后可以写出如下的矩阵乘法:
可以递推,那么这就是最终的矩阵,显而易见的答案就是 $s_n$ ,最后别忘了取模。
这里附上代码:
1 | inline void Work() { |
矩阵类在文章开头的链接里自取
例二:佳佳的斐波那契
佳佳定义 $T(n) = (F_1 + 2F_2 + 3F_3 + \dots+nF_n)\mod m$ ,其中 $F_i$ 表示第 $i$ 个斐波那契数。
显而易见的,我们这里还要更加逆天,要求的是一个从来没见过的东西,于是,我们搬出一个古话:
形数结合百般好,隔离分家万事休。—— 华罗庚
我们可以现尝试把这个 T 数列的计算方式画一画,看看有什么特殊的地方。下面三幅图,从左往右依次为:前缀和中的统计,前缀和的前缀和中的统计, T(n) 的统计。
我们不难发现,前缀和的前缀和中每一个斐波那契数的出现次数和题目要求的 T(n) 中每一个斐波那契数的出现次数相当相似。而前缀和是我们能求的,前缀和的前缀和也使我们能求的。那其实就相当于在一个大方块里面,挖掉一角。而这个大方块的计算方式就是:
那么如何去推这样的矩阵呢?显而易见我们比原来的矩阵多了一个需要求的前缀和,但是肯定也难不倒大家,我的代码用的是第一种,多出来的一维矩阵表示的是 $S(n)$ 表示前 $n-1$ 个前缀和的前缀和。
1 | inline void Work() { |
至此就是所有的基础斐波那契的矩阵快速幂的题目,比较有意思,也给我们提供了数形结合的新思路。