组合数comb

递推法

时间复杂度:O(n*m)

不取模版本

const int N = 60;//N最大为60,否则会爆long long,当初始化需要N,直接给数组开N+10,N取准确值
ll f[N+10][N+10];
void init() {
    for (int i = 0; i <= N; i++) {
        for (int j = 0; j <= i; j++) {
            if (!j) {
                f[i][j] = 1;
                continue;
            }
            f[i][j] = f[i - 1][j - 1] + f[i - 1][j];
        }
    }
}

公式法

时间复杂度:O(n)

[公式]

\[\begin{gathered} \mathrm{C}_n^m=\frac{\mathrm{A}_n^m}{\mathrm{A}_m^m}=\frac{n(n-1)(n-2)\cdots(n-m+1)}{m!} =\frac{n!}{m!(n-m)!},\quad n,m\in\mathbb{N}^*,\text{并且}m\leq n \\ \mathrm{C}_n^0=\mathrm{C}_n^n =1 \end{gathered} \]

const int N = 2000000;
const int mod = 1e9 + 7;

ll inv_fac[N+10], fac[N+10];
ll qmi(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
void init() {
    fac[0] = 1;
    for (int i = 1; i <= N; i++) {
        fac[i] = fac[i - 1] * i % mod;
    }
    inv_fac[N] = qmi(fac[N], mod - 2);
    for (int i = N; i >= 1; i--) {
        inv_fac[i - 1] = inv_fac[i] * i % mod;
    }
}
ll comb(int n, int k) {
    return fac[n] * inv_fac[k] % mod * inv_fac[n - k] % mod;
}
posted @ 2023-12-07 17:51  White_Sheep  阅读(13)  评论(0编辑  收藏  举报