二项式系数modulo 142857

时间:2012-10-28 05:21:56

标签: algorithm math combinatorics binomial-coefficients

如何计算大nr的二项式系数模数142857。 142857有什么特别之处吗?如果问题是模p,其中p是素数,那么我们可以使用卢卡斯定理但是应该为142857做什么。

3 个答案:

答案 0 :(得分:13)

算法是:

  • 将基地分解为主要权力; 142857 = 3 ^ 3×11×13×37
  • 以每个主要力量计算结果
  • 使用Chinese Remainder Theorem结合结果。

计算(n above k) mod p^q

资料来源:http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf,定理1

(n!)_p定义为1..n

不可分割的数字p的乘积 在删除基座n_j中的n个最低有效数字后,

j定义为p

r定义为n - k

e_j定义为添加k+r时的数量,而不计算来自j最低位数的数据,以p为基础进行计算

s定义为1 p=2 & q>=3-1否则

然后(n above k) mod p^q := p^e_0 * s^e_(q-1) * concatenate(j=d..0)( (n_j!)_p / ((k_j!)_p*(r_j!)_p) ),每个连接项计算结果的一个base-p数字,最低j计算最不重要的非零数字。

答案 1 :(得分:12)

您可以在C(n,k) % m时间内为任意O(n)实际计算m

诀窍是将n!k!(n-k)!计算为素数向量,稍后从第一个中减去两个,然后将余数乘以模m 。对于C(10, 4),我们这样做:

10! = 2^8 * 3^4 * 5^2 * 7^1
 4! = 2^3 * 3^1
 6! = 2^4 * 3^2 * 5^1

因此

C(10,4) = 2^1 * 3^1 * 5^1 * 7^1

由于没有分歧,我们可以轻松地计算mod m。诀窍是在线性时间内计算n!和朋友的分解。如果我们预先计算质数为n,我们可以按如下方式有效地执行此操作:显然,对于产品1*2*...*9*10中的每个偶数,我们得到2因子。对于每个第四个数字,我们得到第二个,依此类推。因此,2n!个因素的数量为n/2 + n/4 + n/8 + ...(其中/为地板)。我们对剩余的素数做同样的事情,并且因为O(n/logn)素数小于n,我们O(logn)每个素数都有效,所以分解是线性的。

在实践中,我会更加隐含编码,如下所示:

func Binom(n, k, mod int) int {
    coef := 1
    sieve := make([]bool, n+1)
    for p := 2; p <= n; p++ {
        if !sieve[p] {
            // Sieve of Eratosthenes
            for i := p*p; i <= n; i += p {
                sieve[i] = true
            }
            // Calculate influence of p on coef
            for pow := p; pow <= n; pow *= p {
                cnt := n/pow - k/pow - (n-k)/pow
                for j := 0; j < cnt; j++ {
                    coef *= p
                    coef %= mod
                }
            }
        }
    }
    return coef
}

这包括一个Eratosthenes筛,因此如果使用更快的筛子预先计算或筛分,则运行时间为nloglogn而不是n

答案 2 :(得分:3)

142857的特殊之处在于7 * 142857 = 999999 = 10 ^ 6 - 1.这是由费马的小定理产生的因子,a = 10且p = 7,产生模数等价10 ^ 7 == 10 (mod 7)。这意味着你可以在大多数情况下使用模999999,并在最后除以7减少到最终模数。这样做的优点在于,对于k = 1,2,3,6,模式划分在10 ^ k形式的表示基础中非常有效。在这种情况下你所做的就是将数字组加在一起;这是casting out nines的概括。

如果你有硬件base-10乘法,那么这种优化才有意义。如果你不得不用纸和铅笔做这件事,那真的可以说它很好用。由于这个问题最近出现在网上竞赛中,我想这正是问题的根源。