BZOJ2839 集合计数 题解 二项式反演

题目链接:https://www.luogu.com.cn/problem/P10596

解题思路:完全来自 GhostLX大佬的学习笔记

示例程序:

#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
const int maxn = 1e6 + 5;

long long fpow(long long a, long long b) {
    long long res = 1;
    for (long long t = a % mod; b; b >>= 1, t = t * t % mod)
        if (b & 1ll)
            res = res * t % mod;
    return res;
}

long long inv(long long a) {
    return fpow(a, mod-2);
}

int n, k;
long long fac[maxn] = {1}, two[maxn] = {2}, ans;

void init(int n) {
    for (int i = 1; i <= n; i++) {
        fac[i] = fac[i-1] * i % mod;
        two[i] = two[i-1] * two[i-1] % mod;
    }
}

long long C(int n, int m) {
    return fac[n] * inv(fac[n - m]) % mod * inv(fac[m]) % mod;
}

int main() {
    cin >> n >> k;
    init(n);
    for (int i = k, flag = 1; i <= n; i++, flag = -flag) {
        long long g = C(n, i) * (two[n - i] - 1 + mod) % mod;
        ans = (ans + flag * (C(i, k) * g % mod) + mod) % mod;
    }
    cout << ans << endl;
    return 0;
}
posted @ 2026-04-06 17:35  quanjun  阅读(4)  评论(0)    收藏  举报