C++ 利用模乘逆概念计算nCr%MOD
我正在计算n的大值的nCr%MOD 我使用的关系是(n+1)Cr=(nCr)*(n+1)/(n+1-r) 我必须在循环中迭代不同的n值,保持r不变C++ 利用模乘逆概念计算nCr%MOD,c++,conceptual,C++,Conceptual,我正在计算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
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
概念错误?是的,底部的公式在数学上是正确的 但是,如果在取模之前进行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
您可能也对我的答案感兴趣。我的想法与(a*b)%c=((a%c)*(b%c))%cha除以2时您是否尝试添加后缀ULL或LLU?x/=2LLU;通常在编码时,如果不指定编译器的文本类型,就会产生这种截断问题。