我想用以下约束计算nCk mod m:
N'LT = 10 ^ 18
K&LT = 10 ^ 5
M = 10 ^ 9 + 7
我读过这篇文章:
Calculating Binomial Coefficient (nCk) for large n & k
但是这里m的值是1009.因此,使用卢卡斯定理,我们只需要计算1009 * 1009个不同的aCb值,其中a,b <= 1009
如何使用上述约束来完成。 在给定约束条件下,我无法使O(m * k)空间复杂度数组化。
帮助!
答案 0 :(得分:3)
只需使用
这一事实(n, k) = n! / k! / (n - k)! = n*(n-1)*...*(n-k+1)/[k*(k-1)*...*1]
所以你实际上只有2*k=2*10^5
个因素。对于数字的倒数,您可以使用 kfx 的建议,因为您的m
是素数。
答案 1 :(得分:2)
(n, k)
的二项式系数由公式计算:
(n, k) = n! / k! / (n - k)!
要为大数字n
和k
模数m
进行此操作,请注意:
可以逐步计算模数m
的因子
每一步都取结果% m
。然而,这将是太慢,n高达10 ^ 18。因此faster methods的复杂性受到模数的限制,你可以使用其中的一些。
除法(a / b) mod m
等于(a * b^-1) mod m
,其中b^-1
是b
modulo m
的倒数(即{{1} }})。
这意味着:
(b * b^-1 = 1) mod m
使用Extended Euclidean algorithm可以有效地找到数字的倒数。假设你已经对因子计算进行了整理,算法的其余部分很简单,只需要注意乘法时的整数溢出。此处的参考代码最多可达(n, k) mod m = (n! * (k!)^-1 * ((n - k)!)^-1) mod m
。为了处理更大的数字,应该用更有效的算法替换因子计算,并且应该稍微调整代码以避免整数溢出,但主要思想将保持不变:
n=10^9
答案 2 :(得分:2)
首先,您不需要预先计算和存储所有可能的aCb值!它们可以按案例计算。
第二,对于(k (n选择k)mod m =((n mod m)选择k)mod m 然后(n mod m)&lt; 10 ^ 9 + 7你可以简单地使用@kfx提出的代码。
答案 3 :(得分:0)
我们要计算nCk(mod p)。我将在0 <= k <= p-2时处理,因为卢卡斯定理将处理其余部分。
威尔逊定理指出对于素数p(p-1)! = -1(mod p),或等效地(p-2)! = 1(mod p)(按除法)。
按除法:(k!)^(-1)=(p-2)!/(k!)=(p-2)(p-3)...(k + 1)(mod p)
因此,二项式系数为n!/(k!(nk)!)= n(n-1)...(n-k + 1)/(k!)= n(n-1)。 ..(n-k + 1)(p-2)(p-3)...(k + 1)(mod p)
Voila。您不必进行任何逆计算或类似的操作。编写代码也很容易。需要考虑几个优化:(1)您可以将(p-2)(p-3)...替换为(-2)(-3)...; (2)nCk在nCk = nC(n-k)的意义上是对称的,因此选择需要进行较少计算的一半。