输入
整数“ 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)
我做的第一件事是发现皮萨诺时期(重复余数的时间),其余部分感到困惑。
(简而言之,我不理解上面代码的最后两行)
非常感谢任何提示/指导/参考/解决方案!
答案 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,但它不需要,而且完全脱离上下文。