和和乘法模

时间:2011-05-15 12:15:43

标签: c algorithm math

我有大号KC[1]C[2]C[3]等,我必须计算b:

b = C[1]*C[2]+C[3]*C[4]+... (mod K)

现在我计算完整的总和,然后做出像

这样的东西
b = SUM % K.

但是当SUM变得大于无符号长限时,这不起作用,所以我必须使用像

这样的东西
b = (C[1]*C[2] %K + C[3]*C[4] %K ) %K

但这很费时间。我试过使用unsigned long long,除了unsigned long,这也很耗时。还有更好的办法吗?

UPD:

  C = (unsigned long long int *) malloc(N*sizeof(unsigned long long int));
  unsigned long int i, j, l;
  C[0] = 1;
  for (i=1; i<=N; i++) {
    C[i] = 0;
    l = (unsigned long int) i/2;
    for (j=0; j<l; j++) {
      C[i] += C[j]*C[i-j-1];
      C[i] = C[i] % K;
    }
    C[i] = C[i]*2;
    C[i] = C[i] % K;
    if (i - l*2 == 1) {
      C[i] += C[l]*C[l];
    }
    C[i] = C[i] % K;
  }

3 个答案:

答案 0 :(得分:8)

模数运算是一个环同态。

说f(x)= x%P然后

f(a + b)= f(a)+ f(b)以及

f(a * b)= f(a)* f(b)。

http://en.wikipedia.org/wiki/Modular_arithmetic

这意味着你可以在每一步之后做一个mod P.

答案 1 :(得分:6)

计算

b = ( C[1]*C[2]+C[3]*C[4]+... ) % P 

你可以改为:

b = ( ( (C[1] % P) * (C[2] % P) % P )
    + ( (C[3] % P) * (C[4] % P) % P )
    + ...
    ) % P

由于所有操作的结果都不会超过(P-1)^2,因此如果将所有中间结果保留在类型尽可能小的变量中,我希望这会更快。


如果数字P是某种特殊形式,如2的幂,那么有更快的方法。


在这个问题:big-numbers-in-c中,您会找到对 GNU Multiple Precision Arithmetic Library 的引用。如果你不被允许使用这样的库我想那最好的选择是实现你自己的这个库的一个子集。

你可以在数组中存储整数(大于2 ^ 64),并为这些数字定义加法,重复数据删除,除法和模数函数。

答案 2 :(得分:1)

如果您可以将K分解为pairwise relatively prime个数字K 1 ,...,K n ,那么您可以对每个K 进行计算我并使用Chinese remainder theorem将结果合并到K的结果中。这通常要快得多,特别是如果K i 适合机器词。