【发布时间】:2019-06-24 02:06:41
【问题描述】:
我收到两个警告(缩小转换 && 控制可能到达非 void 函数的结尾),代码如下。然而,代码会编译,当我运行它时它会给出以下消息:Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
代码是在 Ubuntu 上使用 CLion 编译的
// calculate F(n) mod m
#include <iostream>
#include <cmath>
long long Fiobonacci(long long n) { // Fast calculation of Fibonacci number using 'fast doubling'
if (n == 0)
return 0;
else if (n % 2 == 0)
return Fiobonacci(n / 2) * (2 * Fiobonacci(n / 2 + 1) - Fiobonacci(n / 2));
else
return std::pow(Fiobonacci((n + 1) / 2), 2) + std::pow(Fiobonacci((n - 1) / 2), 2);
}
long long GetPissanoPeriod(long long m){
for (long long i = 0; i <= 6 * m ; ++i){
if (Fiobonacci(i) % m == 0){ // if an element is zero it might be followed by a 1
if(Fiobonacci(i+1) % m == 1)
return i+1;
}
}
}
int main() {
long long n, m;
std::cin >> n >> m;
long long period = GetPissanoPeriod(m);
long long res = Fiobonacci(n % period) % m;
std::cout << res << 'n';
}
【问题讨论】:
-
你意识到如果
m是一个素数,你可以用 Zm(也就是整数 mod m)做所有的数学运算并得到相同的结果。如果m不是素数,我想你可以把它分解成素数,然后在每个Zp中进行计算后使用中国剩余定理得到结果。 -
@RezaAfra
return std::pow(Fiobonacci((n + 1) / 2), 2)-- Do not use pow() for integer exponentiation -
此外,您可以利用memoization,而不必为相同的输入重新计算
Fibonacci。将Fibonacci(n)的预计算值存储在一个表中,然后将其用作缓存可能会加快此代码的速度。 -
我应该看到的! 打额头 是的,一般来说,如果你正在用整数做数学运算并且你需要
#include <math>来做某事,那么你可能做错了什么。<math>中的几乎所有内容都用于float或double。 -
@Omnifarious 你的意思是
<cmath>?