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

问题描述 投票:0回答:2

输入

整数'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. 我可以改善/优化上面的代码吗?

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

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

algorithm fibonacci number-theory largenumber mod
2个回答
1
投票

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

F(2 n -1)= Fn)^ 2 + Fn -1)^ 2] >

F

(2 n)=(2 Fn -1)+ Fn))F] >(<< [n您可以在每一步取余数模

m

每个数字都可以表示为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,但它是不需要,完全脱离上下文。


0
投票
每个数字都可以表示为ax + b
© www.soinside.com 2019 - 2024. All rights reserved.