我如何找到大 C(n , r) 的 mod

How do I find mod of large C(n , r)

如何找到 C (n , r) mod k 其中

0 < n,r < 10^5
k = 10^9 + 7 (large prime number)

我找到了使用 Lucas theorem here 解决此问题的链接。

但在我的 n 、 r 、 K 都很大的情况下,这对我没有帮助。这个问题的扩展是:-

求系列之和,如:-

(C(n,r) + C(n, r-2) + C(n, r-4) + ...... ) % k

原始约束保持不变。

谢谢。

这是动态规划的典型用例。帕斯卡三角形给了我们

C(n, r) = C(n-1, r) + C(n-1, r-1)

我们也知道

C(n, n) = 1
C(n, 0) = 1
C(n, 1) = n

您可以对每个子结果应用取模以避免溢出。 时间和内存复杂度都是 O(n^2)

我认为,更快的方法是使用模逆。

复杂度将低至 log(n)

例如

ncr( x, y) % m 将是

a = fac(x) % m;
b = fac(y) % m;
c = fac(x-y) % m;

现在如果你需要计算(a / b ) % m 你可以做到 (a % m) * ( pow( b , m - 2) % m ) // Using Fermat’s Little Theorem

https://comeoncodeon.wordpress.com/2011/10/09/modular-multiplicative-inverse/

我知道复杂度为 O(r*log_n) 的算法 首先看一下在没有 mod k:

的情况下计算 C(n,r) 的算法
int res = 1;
for(int i=1; i<=r; i++){
  res*=(n+1-i);
  res/=i;
}

在你的例子中,你不能除法,因为你使用 mod元运算。但是您可以乘以 mod 元乘法逆元素,有关它的信息,您可以在此处找到 https://en.wikipedia.org/wiki/Modular_multiplicative_inverse。 你的代码将是这样的:

int res = 1;
for(int i=1; i<=r; i++){
  res*=(n+1-i);
  res%=k;
  res*=inverse(i,k);
  res%=k;
}

C(n,r) = n!/(r!(n-r)!) = (n-r+1)!/r!

由于 k 是素数,对于每个 r < k 我们可以使用扩展欧几里得算法在 模乘逆 r^-1 =14=].

因此您可以将 ((n-r+1)!/r) % k 计算为 (((n-r+1)! % k) * r^-1) % k。 重复 1~r 然后你会得到结果。