如何计算nCr%m

时间:2014-11-16 18:25:49

标签: math combinations combinatorics

前提是m not prime如何计算nCr

1 <= n, r <= 100000

就像我们有m素数一样,我们可以做fact(n) * invmod(fact(r)) * invmod(fact(n-r))

其中invmod(a) = power(a, m-2)

如果m不是素数,该怎么办?

1 个答案:

答案 0 :(得分:1)

我们知道

C(n,r) = fact(n)/(fact(r)*fact(n-r))

但考虑C(7,5):

C(7,5) = 7x6x5x4x3x2x1 / (5x4x3x2x1 * 2x1)
       = 7x6 / 2x1

所以想象一下,我们不是做所有的产品,而是用一组价值来做到这一点:

C(7,5) = product( set(1..7) - set(1..5) ) / product(1..2)

但实际上我们可以定义一个交叉取消函数,该函数将一组中的项目取消,并在可能的情况下从第二组中取消值:

crossCancel(numeratorSet, denominatorSet) -> 
   remainingNumers, remainingDenoms

这应该给我们留下需要计算模数的最小乘积,但我们可以更进一步。如果我们将每个剩余的项目分成其因素:

  7x6 / 2
= 7x3x2 / 2

进一步减少会取消2s

= 7x3

实际上,我们知道nCr每次都会取消普通产品(5x4..1),所以我们可以立即将其缩短为

product(set(r+1..n))/product(set(1..n-r))

同样可以证明分母总是取消分子(因为如果r和n由例如3分开,则3将在分母中,3个连续数字将在分子中,因此必须取消) ,所以我们知道我们总能做到

product(set(factorsOf(r+1 .. n)) - set(1..n-r))

鉴于这种现在限制的产品,确定产品模数应该是相当简单的。