对于给定的n和m值,找到fib(n)mod m,其中n非常大。 (皮萨诺时期)

时间:2020-05-10 03:44:46

标签: algorithm fibonacci number-theory largenumber mod

输入

整数“ n”(最多10 ^ 14)和“ m”(最多10 ^ 3)

输出

Fib(n)模m

示例案例

输入:239 1000输出:161 输入:2816213588 239输出:151

问题提示

由于不可能重复'n'次(因为n很大),请考虑使用Pisano周期(每个元素的斐波那契数列除以任何整数时的余数)

我编写的代码(可能是错误的,但通过了上述情况)

n, m = map(int, input().split())
a, b = 0, 1

fib_rems = [0, 1] # remainders after diving 'm'
fib = [0, 1] # regular fibonacci series

while True:

  a, b = b, a+b # cotinuing to grow Fibonacci series
  fib.append(b)
  fib_rems.append(b%m)

  # checking if last two items in remainder are 0, 1 which is indication to pisano period
  if fib_rems[-2] == 0 and fib_rems[-1] == 1:

    # remving last two items in fib and fib_rems which are 1 and 0 so we get length equivalet excatly one period
    fib_rems.pop()
    fib_rems.pop()

    fib.pop()
    fib.pop()

    break

period = len(fib_rems)
rem = n % period
print(fib[rem]%m)

我做的第一件事是发现皮萨诺时期(重复余数的时间),其余部分感到困惑。

  1. 为什么fib(n = 2015)mod 3等同于fib(7)mod 3? (对于?= 3,周期为01120221,长度为8,2015 = 251 * 8 + 7)
  2. 一般来说,得到剩余序列后,如何(数学证明)用于计算Fib(n)mod m?
  3. 我可以改善/优化上面的代码吗?

(简而言之,我不理解上面代码的最后两行)

非常感谢任何提示/指导/参考/解决方案!

2 个答案:

答案 0 :(得分:1)

您可以通过使用二进制幂运算来使其更快。 最终归结为以下两个二次递归关系:

F (2 n -1)= F n )^ 2 + F n -1)^ 2

F (2 n )=(2 F n -1)+ F n )) F n

您可以在每一步取余数 m

答案 1 :(得分:0)

每个数字都可以表示为ax + b

对于n = 2015和m = 3

2015 =(无重复次数)*(无期限)+剩余

0 = <剩余<=期限长度

剩余的值是一个索引,fib(n)的其余部分位于values_in_period数组中。

2015 = 251 * 8 + 7

此外,2015年len(period)= 7

values_in_period = [0,1,1,2,0,2,2,1]

在这种情况下,由于我们的剩余值为7(即fib(n)的其余部分所在的索引),values_in_period的第7个索引就是1!

fib(2015)mod 3可以简化为fib(7)mod 3,因为在斐波那契数列中,每第7个值的其余部分相同,因此为了简化起见可以考虑使用fib(7)mod 3,但它不需要,而且完全脱离上下文。

相关问题