我为n
的大值计算nCr%MOD我使用关系式(n + 1)Cr =(nCr)*(n + 1)/(n + 1-r)
我必须迭代一个循环,以获得不同的n值,保持r不变。
llu fact=1;
/*The loop begins from i>=M+1 */
fact=(fact*(i-1)*modInverse(i-M,MOD))%MOD; // Single statement executed during each iteration of loop
Here I'm calculating (i-1)C(M-1)
Here M and MOD are constant values
MOD=1000000009 and llu refers to unsigned long long
我正在做的是
(n+1)Cr % MOD = [ (nCr) * (n+1) * modInverse(n+1-r) ] % MOD
这里modInverse根据以下定义计算模乘法逆:
llu modPow(llu a, llu x, llu p)
{
//calculates a^x mod p
llu res = 1;
while(x > 0)
{
if( x % 2 != 0)
{
res = (res * a) % p;
}
a = (a * a) % p;
x /= 2;
}
return (res%MOD);
}
llu modInverse(llu a, llu p)
{
//calculates the modular multiplicative of a mod m assuming p is prime
return modPow(a, p-2, p);
}
现在问题是我没有为n的大值(10 ^ 6)得到正确的nCr值。是我的方法
(n+1)Cr % MOD = [ (nCr) * (n+1) * modInverse(n+1-r) ] % MOD
概念上错了?
答案 0 :(得分:0)
是的,底部的公式在数学上是合理的。
然而,通过在取模数之前进行2次乘法,这会增加溢出问题的可能性。
例如,MOD是O(10 ^ 10),因此modInverse也是O(10 ^ 10)。如果n是O(10 ^ 6),则乘积是O(10 ^ 26),这是O(2 ^ 86)并且会导致uint64溢出,并给出错误的答案。请考虑一下:
(n+1)Cr % MOD = [ ([(nCr) * (n+1)] % MOD) * modInverse(n+1-r) ] % MOD
您可能也对我对this suspiciously similar question的回答感兴趣。