巨大的fibonacci模mC++

Huge fibonacci modulo m C++

本文关键字:mC++ fibonacci 巨大      更新时间:2023-10-16

我正在尝试计算Fn mod m,其中Fn是第n个斐波那契数。n可能真的很大,所以用简单的方法计算Fn真的不高效(不过矩阵幂起作用)。问题语句要求我们在不使用模的分配属性计算Fn的情况下执行:(a+b)mod m=[a mod m+b mod m]mod m

(在有人问我之前,我查找了同一个问题的答案。然而,我想要一个特定问题的答案,因为我不是在问算法来解决这个问题)

使用这一点,以及第n个Fibonacci数只是前两个数的和这一事实,我不需要存储Fibonacc数,而只需要存储计算连续模运算的结果。从这个意义上说,我应该有一个大小为n的数组F,它存储了使用上述属性迭代计算Fn-mod m的结果。我使用以下代码解决了这个问题。然而,在回顾它时,我偶然发现了一些让我相当困惑的东西

long long get_fibonacci_huge_mod(long long n, long long m) {
long long Fib[3] = {0, 1, 1};
long long result;
long long index;
long long period;
long long F[n+1];
F[0] = 0;
F[1] = 1;
F[2] = 1;
for (long long i = 3; i <= n; i++) {
F[i] = (F[i-2] + F[i-1]) % m;
if (F[i] == 0 && F[i+1] == 1 && F[i+2] == 1) {
period = i;
break;
}
}

index = n % period;
result = F[index];
return result;
}

这个解决方案输出任何n和m的正确结果,即使它们非常大。当n很大的时候,它可能会变得有点慢,但我现在并不担心。我对用这种方式具体解决问题很感兴趣。稍后我将尝试使用矩阵求幂或任何其他更快的算法来解决它。

因此,我的问题如下。在代码的开头,我创建了一个大小为n+1的数组F。然后我迭代这个数组,使用分配属性计算Fn mod m。在写完这个循环后,有一件事让我感到困惑,那就是,既然F被初始化为全零,如果它们还没有计算出来,那么如何正确地使用F[i+2]、F[i+1]我假设它们被正确使用,因为算法每次都输出正确的结果。也许这个假设是错误的?

我的问题不是关于算法本身,我问的是循环内部发生了什么。

谢谢

这是正确算法的错误实现。让我们先看看修正后的版本。

long long get_fibonacci_huge_mod(long long n, long long m) {
long long result;
long long index;
long long period = n+1;
long long sz = min (n+1,m*m+1); // Bound for period
long long *F = new long long[sz];
F[0] = 0;
F[1] = 1;
F[2] = 1;
for (long long i = 3; i < sz; i++) {
F[i] = (F[i-2] + F[i-1]) % m;
if (F[i] == 1 && F[i-1] == 0) { // we have got back to where we started
period = i-1;
break;
}
}
index = n % period;
result = F[index];
delete[]F;
return result;
}

那么,为什么原始代码可以工作呢?因为你很幸运。由于数组初始化为幸运垃圾,对i+1和i+2的检查从未求值为true。因此,这简化为对F(n)的天真求值,而根本不包含周期性。