我找到了一个解决问题的公式,但我不能让它适用于大数字。第n个因子是第(n-1)个因子+(n-1)*(n-1)+ n * n
所以我写了这个函数:
inline long long int formula(long long int n)
{
if(n==1)return 1;
return formula(n-1)+(n-1)*(n-1)+*n*n;
}
因为答案必须以666013为模计算,所以我添加了这个(MOD = 666013):
inline long long int formula(long long int n)
{
if(n==1)return 1;
return ((formula(n-1)%MOD+(1LL*(n-1)*(n-1))%MOD)%MOD+(1LL*n*n)%MOD)%MOD;
}
我可能没有正确使用模数。我的功能必须适用于大到2.000.000.000的数字,并且它停止工作在大约30.000
编辑:我尝试过使用循环,但仍然无法使其适用于大于20.000.000的数字。这就是我正在使用的:
ans=1;
for(i=2;i<=n;i++)
{
ans=(ans%MOD+1LL*(i-1)*(i-1)%MOD+1LL*i*i%MOD)%MOD;
}
答案 0 :(得分:3)
我不明白你为什么要使用递归函数。它可以在少量的呼叫中工作,但是如果你递归地称它为几百万次,那么......它不会。原因是你在另一个函数中调用另一个函数中的函数...太多次激发程序崩溃或命名为&#34; Stack Overflow&#34;。
克服这种情况的最佳方法是使用循环来修复它!只需从0迭代到n(n是您想要获得的数字)。
答案 1 :(得分:2)
尽可能简化以便能够查看要求:
typedef long long val_t;
#define MOD ((val_t) 666013)
// for really big numbers, change #if to 1
#if 0
#define MODOF(_x) ((_x) % MOD)
#else
#define MODOF(_x) (_x)
#endif
#define SQR(_i) MODOF((_i) * (_i))
val_t
formula(val_t n)
{
val_t i;
val_t ans;
ans = 0;
for (i = 1; i <= n; ++i) {
ans += SQR(i-1);
ans += SQR(i);
ans %= MOD;
}
return ans;
}
更新:我已经习惯于在这里看到我写错了公式的因子。现在纠正了。
答案 2 :(得分:1)
您的代码的迭代版本如下所示。你可以用它
inline long long int formula(long long int n)
{
long long f = 1;
for (int i = 2; i <= n; i++)
{
f = ((f % MOD + (1LL * (i - 1)*(i - 1)) % MOD) % MOD + (1LL * i*i) % MOD) % MOD;
}
return f;
}
答案 3 :(得分:0)
如果您需要计算20亿的大小,那么循环将花费很长时间。然而,递归方程通常导致
sum [i * i+(i-1)*(i-1)] = sum [2* i * i - 2*i + 1].
您可以使用the sum of first n squares的等式和算术序列将其简化为:
2*n(n * n + 1) / 3
现在您可以使用* b%c =(a%c)*(b%c)进一步减少此项。但是,除以3和模数运算不通勤。所以你需要把等式写成
( ((2*(n % MOD)) %MOD) * (((n % MOD) * (n % MOD)) +1) %MOD) * 444009) % MOD
,
其中444009是3 mod MOD的模块化反转,即3 * 444009%MOD = 1。
编辑:添加了关于通勤模数和除法运算符的讨论,正如Raymond Chen指出的模数和除法不通勤。