在最佳时间计算数字的因子

时间:2015-02-06 12:51:33

标签: algorithm factorial

我给了N个数字我想计算一个阶乘模数m的总和 例如

4 100
12 18 2 11

Ans = (12! + 18! +2!+11!)%100

由于1<N<10^5和数字来自1<Ni<10^17 如何在有效的时间内计算它。 由于递归方法将失败,即

int fact(int n){
  if(n==1) return 1;
 return n*fact(n-1)%m;
}

2 个答案:

答案 0 :(得分:1)

如果您使用每个操作%m预先计算阶乘,并且将使用关于大于m的数字的阶乘的注释的提示,您将得到类似的内容

fact = new int[m];
f = fact[0] = 1;
for(int i = 1; i < m; i++)
{
    f = (f * i) % m;
    fact[i] = f;
}

sum = 0
for each (n in numbers)
{
    if (n < m)
    {
        sum = (sum + fact[n]) % m
    }
}

我不确定它是否最好,但它应该在合理的时间内工作。

更新:可以使用以下知识来优化代码:如果对于某些数字j,(j!)%m == 0而不是每个n> j(n!)%m == 0,所以在某些情况下(通常当m不是素数时),没有必要为所有小于m的数字预先计算阶乘法

答案 1 :(得分:0)

试试这个:

var numbers = [12,18,2,11]

function fact(n) {
  if(n==1) return 1;
 return n * fact(n-1);
}

var accumulator = 0
$.each(numbers, function(index, value) {
    accumulator += fact(value)
})

var answer = accumulator%100

alert(accumulator)
alert(answer)

你可以看到它在这里运行:

http://jsfiddle.net/orw4gztf/1/