输入
整数'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)
[我做的第一件事是发现皮萨诺时期(重复余数的时间),其余部分感到困惑。
(总之,我不理解上面代码的最后两行)
非常感谢任何提示/指导/参考/解决方案!
您可以通过使用二进制幂运算来使其更快。最终归结为以下两个二次递归关系:
F(2 n -1)= F(n)^ 2 + F(n -1)^ 2] >
F
(2 n)=(2 F(n -1)+ F(n))F] >(<< [n)您可以在每一步取余数模m
。对于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,但它是不需要,完全脱离上下文。