繁体   English   中英

我如何计算以 k 为模 100003 的大数的 n 组合?

[英]How do i calculate combinations of n taken by k for large numbers in modulo 100003?

n 的最大值是 100 000,k 可以是 0 到 100 000 之间的任何值。问题要求计算模 100 003 的值。所以我使用了一个函数来计算 n、nk 和 k 的阶乘,然后打印fact(n)/(fact(nk)*fact(k))% 100 003. 我做错了什么,解决方案是什么?

    long long int fact (int z)
{
    long long int r;
    if(z<=1)return 1;
    r=1LL*z*fact(z-1);
    return r;
}

long long不足以容纳有趣的 n 的fact(n) ,因此您需要一个更智能的算法。

在乘法时应用 mod 100003 是一种保持范围内的简单方法。 但是模块化划分是混乱的,在这种情况下是不必要的。

考虑如何计算 fact(n)/( fact(nk)*fact(k) ) 而无需除任何大数或模数。

大多数z都会溢出(例如z = 105已经溢出)。

幸运的是,整数模 100003 形成一个字段(因为 100003 是素数),所以整个计算(即使它包括除法)可以模 100003 完成,从而防止任何溢出。

大多数运算都是相同的(除了额外的模运算),但是除法变成了模乘逆的乘法,您可以使用扩展的欧几里得算法找到它。

ncr=n!/((nr)!*r!)

(a/b)%p!=((a%p)/(b%p))%p

使用费马小定理我们可以计算这个

这里 fact() 表示阶乘。

nCr % p = (fac[n] modInverse(fac[r]) % p modInverse(fac[nr]) % p) % p;

这里 modInverse() 表示模 p 下的模逆。

如果 p 是素数,则计算 ,moduloINverse

    long long modInverse( long long n, int p)
    {
        return expo(n, p - 2, p);
    }

 

long long expo(long long a, long long  b, long long mod) {
long long res = 1; 
while (b > 0) {
if (b & 1)res = (res * a) % mod;
a = (a * a) % mod;
b = b >> 1;}
 return res;}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM