C++ 如何用A,B<计算斐波那契(A)模B=10^18英寸C++;(g+;+;)

C++ 如何用A,B<计算斐波那契(A)模B=10^18英寸C++;(g+;+;),c++,algorithm,math,g++,implementation,C++,Algorithm,Math,G++,Implementation,例如,A=10^17,B=10^17(=mod)c-=mod; d=(a*a+b*b);/*F(2n+1)*/ 而(d>=mod)d-=mod; 如果(n%2==0){ ans[0]=c; ans[1]=d; } 否则{ ans[0]=d; ans[1]=c+d; } } int main(){ int T=1000; 长n; 而(T--){ scanf(“%lld%lld”、&n和&mod); long-long-ans[2]={0}; 快速fib(n,ans); printf(“%lld\n

例如,A=10^17,B=10^17(=mod)c-=mod; d=(a*a+b*b);/*F(2n+1)*/ 而(d>=mod)d-=mod; 如果(n%2==0){ ans[0]=c; ans[1]=d; } 否则{ ans[0]=d; ans[1]=c+d; } } int main(){ int T=1000; 长n; 而(T--){ scanf(“%lld%lld”、&n和&mod); long-long-ans[2]={0}; 快速fib(n,ans); printf(“%lld\n”,ans[0]); } 返回0; }
使用uu float128,我无法有效地实现模运算,a、b、c、d必须存储128位数据。

计算不需要任何浮点类型。只能使用
long
类型。首先,您需要一个将两个
long
数(小于
10^18
)乘以模
B
的函数。这可以通过类似的方法完成:

其次,您需要将模运算添加到几乎所有的算术运算中。当(c>=mod)c-=mod时,您肯定需要将这些循环替换为
(它们可能非常慢),在相应的操作中添加
%mod

\uuu float\u 128
替换为
long
并使用适当的模运算的代码:


您可以做的另一件事是使用(如注释中所述)
Boost.Multiprecision
或非标准的
\u int128
类型(如果支持),而不是复杂乘法的
long
类型


另外,你可以使用一个稍微不同的方法(但实际上使用的是相同的数学),这对我来说似乎更明显——斐波那契数矩阵公式


要计算矩阵的
N
th次方,您可以通过对所有运算进行平方运算来使用幂运算,即模
B

“Fibonnacci(A)超过长整型”的可能重复项--不相关,您只需首先计算模B即可。@harold+1:然后,这是mathoverflow的问题。可能重复或您可以选择其他算法清晰的解释(但无代码):这与我在帖子中提到的斐波那契快速倍增算法的问题相同。问题更多的是我可以用来计算它的类型。我已经看到了uu float128,但是我不认为我可以用这个float实现所有的int变量。假设x86_64,
\uu int128
将使乘法更容易。或者使用Boost.Multiprecision类型。注意:这与问题中提供的快速倍增算法基本相同,性能相同。@JamesKPolk,没错。问题的早期版本没有包含任何代码或实现细节,我提出的矩阵方法对我个人来说似乎更为明显。这是另一个有趣的公式。
#include <bits/stdc++.h>
using namespace std;

__float128 a,b,c,d;
long long mod;

void fast_fib(long long n,long long ans[]){
    if(n == 0){
        ans[0] = 0;
        ans[1] = 1;
        return;
    }
    fast_fib((n/2),ans);
    a = ans[0];             /* F(n) */
    b = ans[1];             /* F(n+1) */
    c = 2*b - a;
    if(c < 0) c += mod;
    c = (a * c);      /* F(2n) */
    while(c>=mod)c-=mod;
    d = (a*a + b*b);  /* F(2n + 1) */
    while(d>=mod)d-=mod;
    if(n%2 == 0){
        ans[0] = c;
        ans[1] = d;
    }
    else{
        ans[0] = d;
        ans[1] = c+d;
    }
}

int main(){
  int T=1000;
  long long n;
  while(T--){
    scanf("%lld %lld",&n,&mod);
    long long ans[2]={0};
    fast_fib(n,ans);
    printf("%lld\n", ans[0]);
  }
  return 0;
}
long long multiply(long long a, long long b, long long M) {
    long long res = 0;
    long long d = a;

    while (b > 0) {
        if (b & 1) {
            res = (res + d) % M;
        }
        b /= 2;
        d = (d + d) % M;
    }
    return res;
}