二项式反演

二项式反演

(写这么个玩意也不容易,如果发现有错请及时联系我qwq)

1. 反演的定义

演绎推理是我们在数学中经常遇到的方法。对于数列来说,通过原数列计算出新数列叫作演绎,而通过计算出的数列反推出原数列则被称为反演

举个例子,假设有两个数列 \(f(x)\)\(g(x)\)\(f(x)\) 为原数列,\(g(x)\) 为新数列。我们从 \(f(x)\) 推出 \(g(x)\) 的过程就叫做演绎,而利用 \(g(x)\) 反推出 \(f(x)\)的过程就叫做反演。

一般来说,有了两个数列的相互关系,我们才能相互推算。在一些特定的情况下,相互关系会有一些特殊的性质,人们将重要的、常见的相互关系命名,并深入研究其性质,如二项式反演莫比乌斯反演单位根反演子集反演等。

再举个例子,我们假设 \(g(x)\)\(f(x)\) 满足:

\[\begin{aligned} g(x) &= \sum_{i=0}^x {a_i f(i)} \end{aligned}\]

我们可以利用它们的关系式,从 \(f(x)\) 推到 \(g(x)\),也可以通过解 \(n\) 元一次方程组,从 \(g(x)\) 推到 \(f(x)\)。当然,这个关系式的反演过程只需要简单地进行解方程组,所以并没有特别的名字。

2. 通过容斥原理推导二项式反演

不会容斥原理的可以来看我的另一篇博客

我们设全集 \(U = \{S_1, S_2, \dots, S_{n - 1}, S_n \}\) 中的任意 \(i\) 个元素的并集大小相等,任意 \(i\) 个元素的交集大小也相等。

\(g(n)\) 代表任意 \(n\) 个集合的交集\(f(n)\) 代表任意 \(n\) 个集合的补集的交集。特别地,\(g(0) = f(0) = |U|\)

那么我们就能得到下面两条容斥式子:

\[\begin{aligned} g(n) &= |S_1 \cap S_2 \cap \dots \cap S_{n - 1} \cap S_n| \\ &= |U| - |\overline{S_1}| - |\overline{S_2}| - \dots + (-1)^n \times |\overline{S_1} \cap \overline{S_2} \cap \dots \cap \overline{S_{n-1}} \cap \overline{S_n}| \\ &= \sum_{i = 0}^n(-1)^i \dbinom{n}{i}f(i) \end{aligned}\]

\[\begin{aligned} f(n) &= |\overline{S_1} \cap \overline{S_2} \cap \dots \cap \overline{S_{n - 1}} \cap \overline{S_n}| \\ &= |U| - |S_1| - |S_2| - \dots + (-1)^n \times |S_1 \cap S_2 \cap \dots \cap S_{n-1} \cap S_n| \\ &= \sum_{i = 0}^n(-1)^i \dbinom{n}{i}g(i) \end{aligned}\]

所以我们得到了优美的 一点都不优美的 二项式反演式子:

\[\begin{aligned} g(n) &= \sum_{i = 0}^n(-1)^i \dbinom{n}{i} f(i) \Leftrightarrow f(n) = \sum_{i = 0}^n(-1)^i \dbinom{n}{i}g(i) \end{aligned}\]

3. 二项式反演的常用形式

形式一

已知公式:

\[\begin{aligned} g(n) &= \sum_{i = 0}^n (-1)^i \dbinom{n}{i} f(i) \Leftrightarrow f(n) = \sum_{i = 0}^n (-1)^i \dbinom{n}{i}g(i) \end{aligned}\]

我们假设 \(h(n) = (-1)^n f(n)\),则有:

\[\begin{aligned} g(n) &= \sum_{i = 0}^n \dbinom{n}{i} h(i) \Leftrightarrow \frac{h(n)}{(-1)^n} = \sum_{i = 0}^n (-1)^i \dbinom{n}{i}g(i) \end{aligned}\]

\[\begin{aligned} g(n) &= \sum_{i = 0}^n \dbinom{n}{i} h(i) \Leftrightarrow h(n) = \sum_{i = 0}^n (-1)^{i + n} \dbinom{n}{i}g(i) \end{aligned}\]

而对于整数 \(i\)\(n - i = n + i - 2 \cdot i\),所以在对 \(2\) 取模的意义下,有 \(n + i \equiv n - i\ ( mod\ 2)\)

所以有

\[\begin{aligned} g(n) &= \sum_{i = 0}^n \dbinom{n}{i} h(i) \Leftrightarrow h(n) = \sum_{i = 0}^n (-1)^{n - i} \dbinom{n}{i}g(i) \end{aligned}\]

即常见的:

\[\begin{aligned} g(n) &= \sum_{i = 0}^n \dbinom{n}{i} f(i) \Leftrightarrow f(n) = \sum_{i = 0}^n (-1)^{n - i} \dbinom{n}{i}g(i) \end{aligned}\]

这也就是第一个常用的形式,不过这里 \(g(x)\)\(f(x)\) 的定义视情况而定。

形式二

先给出形式:

\[\begin{aligned} f(n) = \sum_{i = n}^m {i \choose n} g(i) \Leftrightarrow g(n) = \sum_{i = n}^m (-1)^{i - n} {i \choose n} f(i) \end{aligned}\]

将右式代入左式,则

\[\begin{aligned} f(n) &= \sum_{i = n}^m{i \choose n} \sum_{j = i}^m (-1)^{j - i}{j \choose i} f(j)\\ &= \sum_{i = n}^m \sum_{j=i}^m(-1)^{j-i}{i\choose n}{j\choose i}f(j)\\ &= \sum_{j = n}^m f(j) \sum_{i=n}^j(-1)^{j-i}{i\choose n}{j\choose i}\\ &= \sum_{j = n}^m{j \choose n} f(j) \sum_{i=n}^j {j - n\choose j - i} (-1)^{j - i}\\ &= \sum_{j = n}^m{j \choose n} f(j) \sum_{t = 0}^{j - n}{j - n \choose t} (-1)^{t}1^{j-n-t}\\ &= \sum_{j = n}^m{j \choose n} f(j) (1 - 1)^{j - n}\\ &= \sum_{j = n}^m{j \choose n} f(j) [j = n]\\ &= {n \choose n} f(n)\\ &= f(n) \end{aligned}\]

等式两边恒等,故恒成立。

4. 二项式反演在题目中的应用

4.1 几个经典问题

4.1.1 全错位排列问题

错位就是原来在某一位置上的数不能在这个位置上,或者说 \(a_i \ne i\)

全排列就不再解释了

对于这个问题,我们可以定义 \(g(x)\) 表示 \(n\) 个数中,至多\(x\)\(a_i \ne i\) 的总方案数。\(f(x)\) 表示 \(x\) 个数的全错位排列的方案数。

所以有:

\[\begin{aligned} g(n) &= \sum_{i = 0}^n {n \choose i} f(i) \\ \end{aligned}\]

\(g(x)\) 的定义来看,有

\[\begin{aligned} g(x) &= x! \end{aligned}\]

所以我们可以用二项式反演得到 \(f(n)\)

\[\begin{aligned} f(n) &= \sum_{i = 0}^n (-1)^{n - i} {n \choose i} g(i) \\ &= \sum_{i = 0}^n (-1)^{n - i} {n \choose i} i! \\ &= \sum_{i = 0}^n (-1)^{n - i} \frac{n!}{(n - i)!} \end{aligned}\]

在求和式中,把 \(n!\) 提出来,再用 \(i\) 代换 \(n - i\),式子不变,得到

\[\begin{aligned} f(n) &= n! \sum_{i = 0}^n \frac{(-1)^i}{i!} \end{aligned}\]

这也就是所谓的全错位排列公式

4.1.2 第一类斯特林数

想了解斯特林数的可以看看我的另一篇博客,这里只是大概描述一下斯特林数所解决的基本问题。

\(n\) 个不同的球放入 \(m\) 个不同的盒子,要求每个盒子非空,球有多少种方案数。

这里的限制是“非空”,那我们就从这里入手,定义 \(g(m)\) 表示 \(n\) 个不同的球放入 \(m\) 个不同的盒子,至多\(m\) 个盒子非空的方案数,\(f(m)\) 表示 \(n\) 个不同的球放入 \(m\) 个不同的盒子,恰好\(m\) 个盒子非空的方案数。

易得:

\[\begin{aligned} g(m) &= m^n \end{aligned}\]

\[\begin{aligned} g(m) = \sum_{i = 0}^m {m \choose i} f(i) \end{aligned}\]

二项式反演后得:

\[\begin{aligned} f(m) &= \sum_{i = 0}^m (-1)^{m - i} {m \choose i} g(i) \\ &= \sum_{i = 0}^m (-1)^{m - i} {m \choose i} i^n \end{aligned}\]

4.1.3 第二类斯特林数

一样,也在我那篇博客里有详细介绍,这里只是粗略说下所解决的基本问题。

\(n\) 个不同的球放入 \(m\) 个相同的盒子,要求每个盒子非空,球有多少种方案数。

其实它与第一类斯特林数就不同在了盒子是否相同,所以我们的定义与推导过程基本不变,只不过最终的式子再除以 \(m!\) 即可

4.1.3 计数问题

重点就在于怎么找到限制条件 \(/\) 性质,有了限制条件 \(/\) 性质,就能找到 \(g(x)\)\(f(x)\) 的含义,也就能通过二项式反演轻松解决掉问题。

上例题:luogu P4859 已经没有什么好害怕的了

4.1.3.1 题目大意

给定 \(n\),并给定 \(a_1, a_2, \dots, a_n\) 以及 \(b_1, b_2, \dots, b_n\),要求两两配对使得 \(a_i > b_j\) 的对数减去 \(a_i < b_j\) 的对数等于 \(k\) 。(\(0 \le k \le n \le 2000, a, b\) 中无相同元素)

4.1.3.2 分析

比较明显的计数问题。既然明确告诉我们要求恰好有 \(k\) 个,那我们就可以很容易想到我们二项式反演。

4.1.3.3 题解

设有 \(x\)\(a, b\) 满足 \(a > b\),那么有 \(n - x\)\(a, b\) 满足 \(a < b\),也就意味着我们要让 \(x - (n - x) = k\)\(\displaystyle x = \frac{n + k}{2}\)

现在我们要考虑怎么求恰好有 \(x\)\(a > b\),自然过渡到用二项式反演解决。

\(g(x)\) 表示至少有 \(x\)\(a > b\) 的方案数,\(f(x)\) 表示恰好有 \(x\)\(a > b\) 的方案数。

那么有:

\[\begin{aligned} g(x) &= \sum_{i = x}^n {i \choose x} f(i) \Leftrightarrow f(x) = \sum_{i = x}^n(-1)^{i - x} {i \choose x} g(i) \end{aligned}\]

那我们现在就要去考虑如何计算 \(g(x)\)

我们先将 \(a\)\(b\) 分别从小到大排序。设 \(r(i)\) 表示比 \(a_i\) 小的 \(b\) 的个数,\(F(i, j)\) 表示前 \(i\)\(a\) 中(排序后)恰好有 \(j\)\(a > b\) 的方案数。可以列出状态转移方程:

\[\begin{aligned} F(i, j) &= F(i - 1, j) + (r(i) - j + 1) \cdot F(i - 1, j - 1) \end{aligned}\]

\(g(i)\) 就等于 \((n - i)! \cdot F(n, i)\)

有了这些,\(f(\frac{n + k}{2})\) 就很好求了。

4.1.3.4 代码
点击查看代码
#include<bits/stdc++.h>
#define M 2007
#define mod 1000000009
#define int long long   //我习惯不好,别学我

using namespace std;

int n, k, x, ans;
int a[M], b[M], F[M][M], r[M], fac[M], g[M], inv[M];

inline int quick_pow(int base, int p) {
    int res = 1;
    while(p) {
        if(p & 1)
            res = res * base % mod;
        base = base * base % mod;
        p >>= 1;
    }
    return res;
}

inline int C(int a, int b) {return fac[a] * inv[b] % mod * inv[a - b] % mod;}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> k;
    fac[0] = fac[1] = inv[0] = inv[1] = 1;
    for(int i = 2; i <= n; ++ i) {
        fac[i] = fac[i - 1] * i % mod;
        inv[i] = quick_pow(fac[i], mod - 2);
    }
    x = (n + k) >> 1;
    for(int i = 1; i <= n; ++ i)
        cin >> a[i];
    for(int i = 1; i <= n; ++ i)
        cin >> b[i];
    stable_sort(a + 1, a + 1 + n);
    stable_sort(b + 1, b + 1 + n);
    for(int i = 1; i <= n; ++ i)
        r[i] = lower_bound(b + 1, b + 1 + n, a[i]) - b - 1;
    F[0][0] = 1;
    for(int i = 1; i <= n; ++ i) {
        F[i][0] = 1;
        for(int j = 1; j <= i; ++ j)
            F[i][j] = (F[i - 1][j] + (r[i] - j + 1) * F[i - 1][j - 1] % mod) % mod;
    }
    for(int i = x; i <= n; ++ i)
        g[i] = F[n][i] * fac[n - i] % mod;
    for(int i = x; i <= n; ++ i) {
        if((i - x) & 1)
            ans = (ans - C(i, x) * g[i] % mod + mod) % mod;
        else
            ans = (ans + C(i, x) * g[i] % mod) % mod;
    }
    cout << ans;
}

4.2 方法总结

总的来说,把握好至少 \(/\) 至多与恰好的关系是最重要的。

4.2.1 至少与恰好

假设共有 \(n\) 种不同的性质,\(g(x)\) 表示从有若干个元素的集合中,选出若干个至少有 \(x\) 种不同性质的元素的集合总方案数,\(f(x)\) 表示从有若干个元素的集合中,选出若干个恰好有 \(x\) 种不同性质的元素的集合方案数。

那么根据我们刚才的结论,有:

\[\begin{aligned} g(x) &= \sum_{i = x}^n {i \choose x} f(i) \Leftrightarrow f(x) = \sum_{i = x}^n(-1)^{i - x} {i \choose x} g(i) \end{aligned}\]

4.2.1 至多与恰好

假设共有 \(n\) 种不同的性质,\(g(x)\) 表示从有若干个元素的集合中,选出若干个至多有 \(x\) 种不同性质的元素的集合总方案数,\(f(x)\) 表示从有若干个元素的集合中,选出若干个恰好有 \(x\) 种不同性质的元素的集合方案数。

那么根据我们刚才的结论,有:

\[\begin{aligned} g(x) &= \sum_{i = 0}^x {x \choose i} f(i) \Leftrightarrow f(x) = \sum_{i = 0}^x(-1)^{x - i} {x \choose i} g(i) \end{aligned}\]

5. 多元二项式反演 \(/\) 高维二项式反演

(个人感觉挺难的)

5.1 结论

设有 \(m\) 个非负整数 \(n_1, n_2, \dots, n_m\)。假设 \(f(n_1, n_2, \dots, n_m)\)\(g(n_1, n_2, \dots,n_m)\) 都是整数,且:

\[\begin{aligned} g(n_1, n_2, \dots, n_m) &= \sum_{k_i = 0}^{n_i} \prod_{j = 1}^m {n_j \choose k_j} f(k_1, k_2, \dots, k_m) \end{aligned}\]

那么有:

\[\begin{aligned} f(n_1, n_2, \dots, n_m) &= \sum_{k_i = 0}^{n_i} \prod_{j = 1}^m (-1)^{n_j - k_j} {n_i \choose k_i} g(k_1, k_2, \dots, k_m) \end{aligned}\]

注:

\( \displaystyle \sum_{k_i = 0}^{n_i} = \begin{matrix} \underbrace{\sum_{k_1 = 0}^{n_1} \dots \sum_{k_i = 0}^{n_i} \dots \sum_{k_m = 0}^{n_m}}\\共m个\end{matrix} \)

5.2 证明

既然你已经看到这里了,说明你很强了,所以我接下来就不写那么细了

我们先来证明一个小东西 恶心人的东西,我们一会需要用到:

\[\begin{aligned} \sum_{i=j}^n(-1)^{n-i}\dbinom{n}{i}\dbinom{i}{j}=[j=n] \end{aligned}\]

证明如下:

\[\begin{aligned} \sum_{i=j}^n(-1)^{n-i}\dbinom{n}{i}\dbinom{i}{j} &= \sum_{i=0}^{n-j}(-1)^{n-i-j}\dbinom{n}{i+j}\dbinom{i+j}{j}\\ &=\dbinom{n}{j}\sum_{i=0}^{n-j}(-1)^{n-i-j}\dbinom{n-j}{n-i-j} \end{aligned}\]

\(n = j\) 时,原式等于 \(1\)

\(n \not= j\) 时,原式利用二项式定理可以继续化简:

\[\begin{aligned} \dbinom{n}{j}\sum_{i=0}^{n-j}(-1)^{n-i-j}\dbinom{n-j}{n-i-j} &=\dbinom{n}{j}(1-1)^{n-j}\\ &= 0 \end{aligned}\]

得证。

我们再继续证我们最初要证的东西:

\[\begin{aligned} \sum_{k_i=0}^{n_i}\prod_{i=1}^m(-1)^{n_i-k_i}\dbinom{n_i}{k_i}g(k_1,k_2,\cdots,k_m) &=\sum_{k_i=0}^{n_i}\prod_{i=1}^m(-1)^{n_i-k_i}\dbinom{n_i}{k_i}\sum\limits_{t_i=0}^{k_i}\prod^m_{i=1}\dbinom{k_i}{t_i}f(t_1,t_2,\cdots,t_m)\\ &=\sum_{t_i=0}^{n_i} \sum_{k_i=t_i}^{n_i}\prod_{i=1}^m(-1)^{n_i-k_i}\dbinom{n_i}{k_i}\dbinom{k_i}{t_i} f(t_1,t_2,\cdots,t_m) \end{aligned}\]

利用刚刚证明的引理,我们可以发现只有当 \(t_1 = n_1, t_2 = n_2, \dots, t_m = n_m\) 时,\(\displaystyle \sum_{k_i=t_i}^{n_i}\prod_{i=1}^m(-1)^{n_i-k_i}\dbinom{n_i}{k_i}\dbinom{k_i}{t_i} f(t_1,t_2,\cdots,t_m)\) 的值才不为 \(0\),为 \(f(n_1, n_2, \dots, n_m)\)

所以原式等于 \(f(n_1, n_2, \dots, n_m)\),得证。

5.3 例题

一道简单的 恶心的 二元 \(/\) 二维二项式反演

CF997C Sky Full of Stars

式子给你,我就不写题解了(你自己写着玩去吧,我懒

\[\begin{aligned} f(x, y) &= \sum_{i = n}^x \sum_{j = m}^y {x \choose i} {y \choose j} g(i,j) \Leftrightarrow g(x,y) = \sum_{i = n}^x \sum_{j = m}^y (-1) ^ {x + y - i - j} {x \choose i} {y \choose j} f(i,j) \end{aligned}\]

6. 总结 \(/\) 后记

二项式反演在很多问题中用处还是不小的,尤其是计数问题,很多都用到了二项式反演,有能力的话还是搞得明白一点比较好。

(呃呃呃,终于写完了,整个人都不好了)

(写这么个玩意也不容易,如果发现有错请及时联系我qwq)

posted @ 2023-08-16 06:40  流星Meteor  阅读(1159)  评论(1)    收藏  举报