微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何找到巨大数字的斐波那契和?

如何解决如何找到巨大数字的斐波那契和?

我正在解决一个 CSES 问题,在该问题中我必须找到前“n”个斐波那契数的总和。代码

#pragma GCC optimize("Ofast")
#include <iostream>
 
using namespace std;
 
int main()
{
    unsigned long long int n;
    scanf("%llu",&n);
    unsigned long long int seq[n];
    seq[0] = 0;
    seq[1] = 1;
    unsigned long long int mod = 1000000000 + 7;
    for (unsigned long long int i = 2; i < n + 1; i++) {
        seq[i] = (seq[i - 1] + seq[i - 2]) % mod;
    }
    cout << seq[n];
}

问题指定 n 的值可以达到 10^18,因此我使用 unsigned long long int 来初始化 n。该问题还指示给出模 7 的答案。该代码适用于最多 4 位数的 n 值,但在 n 值上升到 10^18 的上限时中断。它给出了 (0xC00000FD) 错误并且不返回任何内容。请帮助我理解这里的问题以及如何处理它。任何其他建议也将不胜感激。

解决方法

在进行模块化添加时,您需要将 mod 应用于您添加的每个值。

例如,(a + b) % c = (a % c + b % c) % c。

这意味着在您的代码中:

seq[i] = (seq[i - 1] % mod + seq[i - 2] % mod) % mod;

否则,seq[i - 1]seq[i - 2] 的相加会导致溢出。

阅读有关模算术 here 的更多信息。

,

在这个问题中

F[i] -> 第 i 个斐波那契数。 MOD = 1e9 + 7. n

F[n] % MOD = ?

F[n] = F[n-1] + F[n-2] 如果你用循环计算这个,你会得到 TL

这样你就可以优化这个解决方案

现在你用递归计算 F[n]

F[2*n] = - F[n] * F[n] + 2 * F[n] * F[n+1]

F[2*n+1] = F[n] * F[n] + F[n+1] * F[n+1]

这是我的解决方案

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll MOD = 1e9+7;
void fib(ll n,ll &a,ll &b){
    if(n == 0){
        a = 0;
        b = 1;
        return;
    }
    ll x,y;
    if(n%2==1){
        fib(n-1,x,y);
        a = y;
        b = (x+y)%MOD;
        return;
    }
    fib(n/2,y);
    a = (x*(2*y +MOD -x)%MOD)%MOD;
    b = ((x*x)%MOD+(y*y)%MOD)%MOD;
    return;
}
int main(){
    ll N,a,b;
    cin >> N;
    fib(N,b);
    cout << a;
}
,

我认为这段代码的问题在于您正在创建一个大小为 seq[n] 的数组 n,这可能导致 Linux 上的 SEGFAULT 和 Windows 上的 STATUS_STACK_OVERFLOW (0xc00000fd)对于大数,这是指堆栈耗尽。

下面我给出了你算法的改进版本,它使用固定的内存大小,对于模加,我使用sum_by_modulo函数,以避免(a + b) % m运算中的溢出,其原理被描述为 here

#pragma GCC optimize("Ofast")
#include <iostream>
 
typedef unsigned long long int ullong;

ullong sum_by_modulo(ullong a,ullong b,ullong m){
    ullong sum;
    a %= m;
    b %= m;
    ullong c = m - a;

    if (b==c)
        sum = 0;
    if (b<c)
        sum = a + b;
    if (b > c)
        sum = b-c;
    return sum;
}

int main()
{
    ullong n;
    ullong t1 = 0,t2 = 1,nextTerm = 0;
    ullong modulo = 1000000000 + 7;    

    std::cout << "Enter the number of term: ";
    std::cin >> n;

    for (ullong i = 1; i <= n; ++i)
    {
        if(i == 1)
            continue;
        if(i == 2)
            continue;
        nextTerm = sum_by_modulo(t1,t2,modulo);
        t1 = t2;
        t2 = nextTerm;
    }
    std::cout << nextTerm << " ";
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。