二项式反演 学习笔记

前言

  • 感谢学姐 Estelle_N(应该没打错)
  • msjing之前自学过二反但是直接从入门到出门了,听完学姐讲课后就会了/bx

前置芝士

二项式反演

  • \(f_n\) 为恰好使用 \(n\) 个不同元素形成特定结构的方案数,\(g_n\) 为从 \(n\) 个不同元素中选出 \(i \ge 0\) 个元素形成特定结构的总方案数(即至少)
  • 那么我们有
$g_n = \sum\limits_{i=0}^{n}{\binom{n}{i} \times f_i}$
$f_n = \sum\limits_{i=0}^{n}{\binom{n}{i} \times (-1)^{n-i} \times g_i}$
  • 上述从 \(f_n\)\(g_n\) 和从 \(g_n\)\(f_n\) 的过程成为二项式反演

证明

  • 我们证明 \(f_n = \sum\limits_{i=0}^{n}{\binom{n}{i} \times (-1)^{n-i} \times g_i}\)
  • 我们先把 \(g_n = \sum\limits_{i=0}^{n}{\binom{n}{i} \times f_i}\) 带入,有
$f_n = \sum\limits_{i=0}^{n}{\binom{n}{i}} \times (-1)^{n-i} \times \sum\limits_{j=0}^{i}{\binom{i}{j} \times f_j}$
  • \(\sum\limits_{j=0}^{i}\) 提前,有
$\sum\limits_{i=0}^{n} \sum\limits_{j=0}^{i} \binom{n}{i} \binom{i}{j} \times (-1)^{n-i} \times f_j$
  • 利用组合数,有
$\binom{n}{i} \binom{i}{j} = \binom{n}{j} \binom{n - j}{i - j}$
  • 我们知道 \(\sum\limits_{j=0}^{i}\) 表示 \(j\) 是从 \(0\)\(i\),所以我们换一下枚举,把 \(\sum\limits_{i=0}^{n} \sum\limits_{j=0}^{i}\) 改为 \(\sum\limits_{j=0}^{n} \sum\limits_{i=j}^{n}\)
  • 就有
$\sum\limits_{j=0}^{n}{f_j \times \binom{n}{j}} \sum\limits_{i=j}^{n}{ \binom{n - j}{i - j} \times (-1)^{n-i} }$
  • 我们令 \(k = i - j\),有
$\sum\limits_{j=0}^{n}{f_j \times \binom{n}{j}} \times \sum\limits_{k=0}^{n-j}{ \binom{n-j}{k} \times (-1)^{n-j-k} }$
  • 我们先搞二项式定理,这个先放着,一会说为什么
  • 我们令 \(x = 1 , y = -1\),带入二项式定理,有
$(1 - 1)^n = \sum\limits_{i=0}^{n}{\binom{n}{i} \times (-1)^{n-i}}$
  • \(n \neq 0\) 时,原式 \(=0\),当 \(n = 0\) 时,原式 \(=1\)
  • 吊不吊,\(0^0 = 1\)(貌似可能会伪?)
  • 我们观察二项式定理和上面我们推的柿子,发现后面的那个 \(\sum\) 和二项式定理长得很像,我们类比一下有:\(i \to k , n \to n - j\),其中,\(\to\) 指二项式的元素对应推出的柿子中的元素,然后类比带入,有关键结论:
$C_n = \left\{ \begin{array} &0 & n \neq j\\ 1 & n = j \end{array} \right.$
  • 我们令 \(\sum\limits_{k=0}^{n-j}{ \binom{n-j}{k} \times (-1)^{n-j-k} }\) 的值为 \(val\)
  • \(n \neq j\) 时,\(val = 0\),总柿子结果为 \(0\),不管这种情况
  • \(n = j\) 时,\(val = 1\),柿子化为:
$\sum\limits_{j=0}^{n}{f_j \times \binom{n}{j}}$
  • \(j\) 换成 \(i\),改一下元素位置,就有:
$\sum\limits_{i=0}^{n}{\binom{n}{i} \times f_i}$
  • 这个柿子是等于 \(f_n\) 的,命题得证
  • 证另一个同理,不证了

应用与例题

  • 二项式反演的应用非常广,通常用于至少恰好恰好至少,来两道例题搞一搞
  • sbmqwm:你要考研啊

例题

P10596 BZOJ2839 集合计数

  • 题目要求至少一个,相当于求 \(g_n\),我们发现并不是很好求,所以考虑用二项式反演换成求 \(f_n\),这就很好搞了
  • 我们任意取一个 \(k\),令 \(k\) 表示 \(k\) 个元素作为集合的交集,其余不要求的方案数,有:
$f_k = \binom{n}{k} \times (2^{2^{n-k}} - 1)$
  • 又有:
$f_k = \sum\limits_{i=k}^{n}{\binom{i}{k} g_i}$
  • 利用二反,有答案公式:
$g_k = \sum\limits_{i=k}{n}{(-1)^{i-k} \binom{n}{i} \binom{i}{k} (2^{2^{n-k}} - 1)}$
  • 你把 \(\binom{n}{i} \binom{i}{k}\) 换了好像也可以,给代码
  • 可能代码和讲的不太一样,毕竟是再学习
点击查看代码
#include<bits/stdc++.h>
using namespace std;
constexpr int maxn=1e6+10,p=1000000007;
int read() {int x=0,f=1;char ch=getchar();while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
int n,k;
struct Combinatorics
{
	long long f[maxn],g[maxn];
	long long ksm(long long x,long long y,long long mo)
	{
		long long cnt=1;
		while(y)
		{
			if (y&1) cnt=(cnt*x)%mo;
			x=(x*x)%mo;
			y>>=1;
		}
		return cnt;
	}
	long long NY(long long a,long long p) {return ksm(a,p-2,p);}
	void getfg(long long n)
	{
		f[0]=g[0]=1;
		for (long long i=1;i<=n;i++) (f[i]=i*f[i-1])%=p,g[i]=NY(f[i],p);
	}
	long long getC(long long x,long long y) {return ((f[x]*g[x-y])%p*g[y])%p;}
	long long getA(long long x,int y) {return f[x]*g[x-y]%p;}
	long long d[maxn];
	void getD(long long n)
	{
		d[1]=0,d[2]=1;
		for (long long i=3;i<=n;i++) (d[i]=(i-1)*(d[i-1]+d[i-2])%p+p)%=p;
	}
}c;
int main()
{
	n=read(),k=read();
	c.getfg(n);
	long long fk=0;
	for (int i=k;i<=n;i++) (fk+=c.ksm(-1,i-k,p)*c.getC(i,k)%p*c.getC(n,i)%p*(c.ksm(2,c.ksm(2,n-i,p-1),p)-1)%p)%=p;
	printf("%lld\n",(fk+p)%p);
	return 0;
}

P4859 已经没有什么好害怕的了

  • 没写,咕咕咕

后话

  • msjing on 26.7.20:别用二反乱艹题,上午打 \(ACM\) 欢乐赛盯着随机化的题看了 \(1\) 个小时
posted @ 2026-07-19 21:17  msjing  阅读(17)  评论(2)    收藏  举报