一种快速求组合数的方法

介绍一种快速求 \(\dbinom{n}{m}\) 的方法。

我们知道 \(\dbinom{n}{m} \mod (1e9+7)=\frac{n\times (n-1)\times\dots\times(n-m+1)}{1\times 2\times\dots\times m} \mod (1e9+7)\)

为方便表达,我们设 \(x=n\times (n-1)\times\dots\times(n-m+1)\) (即右边的分子),\(y=1\times 2\times\dots\times m\) (即右边的分母)。

然后就有

\[\dbinom{n}{m} \mod (1e9+7)=\frac{x}{y} \mod (1e9+7)\]

由费马小定理得

\[y \times y^{(10^9+7)−2} \mod (10^9 + 7) = 1\]

两边同时乘上 \(y^{-1}\)

\[y^{(10^9+7)-2} \mod (10^9+7)=y^{-1}\]

因为 \(y^{-1}\)\(y\) 的逆元,所以就有

\[\frac{x}{y} \mod(10^9+7) = x \times y^{(10^9+7)-2} \mod (10^9+7)\]

代码实现起来也不难。

inline LL qpow(LL a, LL b) //快速幂,用于求逆元
{
    LL res = 1;
    while (b)
    {
        if (b & 1) res = (res * a) % mod;
        a = a * a % mod, b >>= 1;
    }
    return res % mod;
}

inline LL work(int n, int m) //求 C(n, m)
{
    LL s = 1, c = 1;
    for (int i = 1; i <= m; i+=1)
        s = (s * i) %mod; //计算分母
    for (int i = n - m + 1; i <= n; i++) 
        c = (c * i) % mod; //计算分子
    return (c * qpow(s, mod - 2)) % mod; //求出值
}

P.S. 部分参考自 AtCoder Beginner Contest 156 D题题解

猜你喜欢

转载自www.cnblogs.com/xsl19/p/12347760.html
今日推荐