の組み合わせの数を求めるための迅速な方法

高速シーク説明\(\ dbinom {N} { M} \) 方法。

我々が知っている\(\ dbinom {N} { M} \ MOD(1E9 + 7)= \ FRAC {N \倍(N-1)\回\ドット\倍(N-M + 1)} {1 \ 2倍\タイムズ\ DOTS \ M}タイムズ\ MOD(+ 1E9 7)\)

発現を促進するために、我々は、セット- \(。。M + 1)\ X = N- \タイムズ(N - 1)\時間\ DOTS \タイムズ(N) すなわち、右上の分子)、\ 。(Y = 1 \ 2倍\タイムズ\ DOTS \タイムズM \) 即ち、右側分母)。

そして、そこに

\ [\ dbinom {N} {M} \ MOD(1E9 + 7)= \ FRAC {X} {Y} \ MOD(1E9 + 7)\]

フェルマーの小定理の

\ [Y \回^ {(^ 9 + 7 10)-2} \ MOD(10 ^ 9 + 7)= 1 \]

両側を同時にによって(y ^ { - 1} \ \) 与えること

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

ので\(Y ^ { - 1} \) である\(Yは\)だから、逆であります

\ [\ FRAC {X} {Y} \ MOD(10 ^ 9 + 7)= X \回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; //求出值
}

基準の部分からPS AtCoder初心者コンテスト156 Dの問題の説明

おすすめ

転載: www.cnblogs.com/xsl19/p/12347760.html