【发布时间】:2010-12-02 22:42:24
【问题描述】:
谁能给我一个关于大 n(比如 10^10)的有效算法的想法,以找到上述系列的总和?
Mycode 在 n=100000 和 m=200000 时被淘汰
#include<stdio.h>
int main() {
int n,m,i,j,sum,t;
scanf("%d%d",&n,&m);
sum=0;
for(i=1;i<=n;i++) {
t=1;
for(j=1;j<=i;j++)
t=((long long)t*i)%m;
sum=(sum+t)%m;
}
printf("%d\n",sum);
}
【问题讨论】:
-
Aviator:高效算法通常独立于语言。这是 Java 还是 C 并不重要(运行时可能是线性因素除外)。
-
@Johannes:我明白了。我想建议 BigInteger。这就是为什么问
-
你说你想要大 n (10^10) 的东西快,但你没有说 m 是否同样大,或者它是否保持在 200k 左右。这可能很重要,因为如果 m 很小,那么您可以尝试预先计算/缓存一些术语。如果您已经知道所有 a 小于 m 的 a^m 和 a^a,那么当您计算 (m+2)^(m+2) 时,它就是 2^(m+2) = 2^m* 2^2。然后 (m+3)^(m+3) = 3^m*3^3 依此类推。您可能可以安排一些事情,以便您始终按顺序访问存储的值,不确定。
-
考虑一下,在计算 2m+1 ... 3m-1 项时,您可能还想缓存 1^2m ... (m-1)^2m .然后使用这些值计算 1^3m ... (m-1)^3m,并将存储的值替换为用于计算 1^4m ... (m-1)^4m 的新值。如果不编写代码,我不知道这是否真的会比 Mehrdad 的 solutino 更快,但除非我错过了致命的东西,否则它是 O(n) 而不是 O(n log n)。显然需要 O(m) 内存。
-
哦,使用 Mehrdad 的代码计算缓存值需要 O(m log m) 时间。因此,如果 m 与 n 一起增长,它可能根本没有帮助,但如果 m 是有界的,它可能是一种改进。