超级斐波那契数列

题目描述:我们现在定义a 1=1,a 2=1,a 3=1,a 4=1,a 5=1,在定义一个递推式:

求第n项的值 模1000000003后的结果  

其中,n的范围可以是1到3467823658764287541943278594275935


思路

如果我们根据这个式子递推肯定是超时的,因此我们可以使用两种trick:1、递推式转化为矩阵  2、矩阵的快速幂

1、传统斐波那契数列可以写成下面矩阵的形式,因此,我们可以通过[[1,1],[1,0]]这个矩阵的n次幂 乘以初始的第2项和第1项,得到第n项

               

推广到我们这一题,这个矩阵就是[[2018, 2017, 2016, 2015, 2014], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0]]


2、如何快速计算矩阵的n次幂的问题

2的20次幂可以分解为2的16次幂乘以2的4次幂,2的16次幂可以分解为2的8次幂的平方。

下面是Python实现

import sys
import numpy as np

class Solution:

    def function(self, n):
        if n < 5:
            return 1
        ans = [1, 1, 1, 1, 1]
        m = np.array(
            [[2018, 2017, 2016, 2015, 2014], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0]])
        a = np.eye(5)
        temp = n - 4
        while temp != 0:
            if temp & 1:
                a = np.matmul(a, m)%1000000003
            if temp == 1:
                break
            a = np.matmul(a, a)%1000000003
            temp = temp >> 1
        res = np.matmul(a, ans)
        return int(res[0])

flag = True
f = Solution()
while (flag):
    a = sys.stdin.readline().strip()
    if a:
        n = int(a)
        # print(n)
        print(f.function(n))
        continue
    flag = False

你可能感兴趣的:(算法)