简体   繁体   English

巨大的斐波那契模数 m C++

[英]Huge fibonacci modulo m C++

I'm trying to calculate Fn mod m, where Fn is the nth Fibonacci number.我正在尝试计算 Fn mod m,其中 Fn 是第 n 个斐波那契数。 n may be really huge, so its really not efficient to calculate Fn in a straightforward way (matrix exponentiation would work, though). n 可能真的很大,因此以直接的方式计算 Fn 确实效率不高(尽管矩阵求幂可以工作)。 The problem statement asks us to do this without calculating Fn, using the distributive property of the modulo: (a+b)mod m = [a mod m + b mod m] mod m问题陈述要求我们在计算 Fn 的情况下使用模的分配特性来做到这一点: (a+b)mod m = [a mod m + b mod m] mod m

(Before anyone asks me, I looked up answers to this same problem. I'd like an answer to my specific question, however, since I'm not asking about the algorithm to solve this problem) (在有人问我之前,我查找了同一问题的答案。但是,我想回答我的具体问题,因为我不是在问解决这个问题的算法

Using this and the fact that the nth Fibonacci number is just the sum of the previous two, I don't need to store Fibonacci numbers, but rather only the results of calculating successive modulo operations.使用这个和第 n 个斐波那契数只是前两个之和的事实,我不需要存储斐波那契数,而只需要计算连续模运算的结果。 In that sense, I should have an array F of size n which has in it stored the results of iteratively calculating Fn mod m using the above property.从这个意义上说,我应该有一个大小为 n 的数组 F,其中存储了使用上述属性迭代计算 Fn mod m 的结果。 I have managed to solve this problem using the following code.我已经设法使用以下代码解决了这个问题。 However, upon reviewing it, I stumbled upon something that rather confused me.然而,在回顾它时,我偶然发现了一些让我感到困惑的事情。

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;

}

This solution outputs correct results for any n and m, even if they are quite large.该解决方案输出任何 n 和 m 的正确结果,即使它们非常大。 It might get a little bit slow when n is huge, but I'm not worried about that right now.当 n 很大时它可能会变慢,但我现在并不担心。 I'm interested in specifically solving the problem this way.我有兴趣以这种方式专门解决问题。 I'll try solving it using matrix exponentiation or any other much faster algorithm later .我会尝试使用矩阵幂或任何其他快得多算法解决它。

So my question is as follows.所以我的问题如下。 At the beginning of the code, I create an array F of size n+1.在代码的开头,我创建了一个大小为 n+1 的数组 F。 Then I iterate through this array calculating Fn mod m using the distributive property.然后我遍历这个数组,使用分布属性计算 Fn mod m。 One thing that confused me after writing this loop was the fact that, since F was initialized to all zeros, how is it correctly using F[i+2], F[i+1], if they haven't been calculated yet?在编写这个循环后让我感到困惑的一件事是,由于 F 被初始化为全零,如果 F[i+2]、F[i+1] 尚未计算,那么如何正确使用它们? I assume that they are being correctly used since the algorithm outputs correct results every time.我假设它们被正确使用,因为算法每次都会输出正确的结果。 Perhaps this assumption is wrong?也许这个假设是错误的?

My question isn't about the algorithm per se, I'm asking about what's going on inside the loop.我的问题不是关于算法本身,而是关于循环内部发生了什么。

Thank you谢谢

This is a faulty implementation of a correct algorithm.这是正确算法的错误实现。 Let us look at the corrected version first.让我们先看看修正后的版本。

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;

}

So why does the original code work?那么为什么原始代码有效呢? Because you got lucky.因为你很幸运。 The checks for i+1 and i+2 never evaluated to true because of the lucky garbage the array was initialized to.由于数组被初始化为幸运垃圾,因此对 i+1 和 i+2 的检查从未评估为真。 As a result this reduced to the naive evaluation of F(n) without incorporating periodicity at all.结果,这简化为对 F(n) 的幼稚评估,而根本不包含周期性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM