# Uses python3
# Given two integers n and m, output Fn mod m (that is, the remainder of Fn when divided by m
def Huge_Fib(n,m):
if n == 0 : return 0
elif n == 1: return 1
else:
a,b = 0,1
for i in range(1,n):
a, b = b, (a+b) % m
print(b);
n,m = map(int, input().split());
Huge_Fib(n,m);
代码效果很好。但是,当我运行一个案例为n = 99999999999999999,m = 2时,我需要花费很多时间。你有更好的解决方案吗?
答案 0 :(得分:3)
ifPresent
这是一个超快的解决方案,请参考https://stackoverflow.com/a/23462371/3700852
答案 1 :(得分:2)
在下面的代码中,我们使用斐波那契数列的两个概念:
Pisano周期遵循斐波那契数列,因此每个重复(模式)都以0和1开头,一个接一个地出现。
fib(n)仅在n除以m时才除以fib(m),这意味着fib(4)%3 == 0时,则fib(4 + 4)%3 == 0,fib(4+ 4 + 4)%3 == 0,依此类推。这有助于我们找到皮萨诺时期。
要了解皮萨诺时期,我建议您观看以下视频:https://www.youtube.com/watch?v=Nu-lW-Ifyec
#python3
def pisano_length(m):
i=2
while(fib(i)%m!=0):
i+=1
if(fib(i+1)%m!=1):
while(fib(i+1)%m!=1):
i+=i
print("The pisano length for mod {} is: {}".format(m,i))
return(i)
def fib(n):
a,b=0,1
if(n==0 or n==1):
return n
else:
for i in range(2,n+1):
b,a=a+b,b
return(b)
#we want to calculate fib(n)%m for big numbers
n,m=map(int,input().split())
remainder=n%pisano_length(m)
print(fib(remainder)%m)
答案 2 :(得分:1)
这是我的解决方案,如果你发现pisano时期,你不必经历99999999999999999次迭代。
我还建议您观看此视频:https://www.youtube.com/watch?v=Nu-lW-Ifyec
# Uses python3
import sys
def get_fibonacci_huge(n, m):
if n <= 1:
return n
arr = [0, 1]
previousMod = 0
currentMod = 1
for i in range(n - 1):
tempMod = previousMod
previousMod = currentMod % m
currentMod = (tempMod + currentMod) % m
arr.append(currentMod)
if currentMod == 1 and previousMod == 0:
index = (n % (i + 1))
return arr[index]
return currentMod
if __name__ == '__main__':
input = sys.stdin.read();
n, m = map(int, input.split())
print(get_fibonacci_huge(n,m))
答案 3 :(得分:0)
你应该查看皮萨诺时期。 https://en.wikipedia.org/wiki/Pisano_period和 http://webspace.ship.edu/msrenault/fibonacci/fibfactory.htm应该让你很好地理解它们是什么。
编辑:只需谷歌搜索&#34;斐波那契模数&#34;给你这两个作为前两个结果。
答案 4 :(得分:0)
对于任何整数m>=2
,模数m的序列fn是周期的-Pisano周期。
因此,无需存储和查找fn。而是找到给定m的重复模式。
答案 5 :(得分:0)
这就是我计算pisano周期的方式。(Java)
public static long get_pisano_period(long m) {
long a = 0, b = 1;
long c;
for (int i = 0; i < m * m; i++) {
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
return i + 1;
}
return 0;
}
public static BigInteger get_fibonacci_huge(long n,long m) {
long remainder = n % get_pisano_period(m);
BigInteger first = BigInteger.valueOf(0);
BigInteger second=BigInteger.valueOf(1);
BigInteger m1=BigInteger.valueOf(m);
BigInteger res = BigInteger.valueOf(remainder);
for (long i = 1; i < remainder; i++) {
res = (first.add(second)).mod(m1);
first = second;
second = res;
}
return res.mod(m1);
}
答案 6 :(得分:0)
我在Python 3中解决了这个问题。这是计算m的巨大斐波那契数的最快算法。例如,对于n = 2816213588,m = 239,它花费的最大使用时间:0.01 / 5.00,最大使用的内存:9424896 / 536870912。)
def pisanoPeriod(m):
previous, current = 0, 1
for i in range(0, m * m):
previous, current = current, (previous + current) % m
# A Pisano Period starts with 01
if (previous == 0 and current == 1):
return i + 1
def calc_fib(n,m):
p = pisanoPeriod(m)
n = n % p
if (n <= 1):
return n
else:
previous,current = 0,1
for i in range(2,n+1):
previous,current = current,(previous+current)
return current%m
n,m =map(int,input().split(" "))
print(calc_fib(n,m))