二项式反演

二项式反演

形式一:

f ( n ) = ∑ i = 0 n ( − 1 ) i ( n i ) g ( i ) f(n)=\sum\limits_{i=0}^n(-1)^i\binom{n}{i}g(i) f(n)=i=0n(1)i(in)g(i),有
g ( n ) = ∑ i = 0 n ( − 1 ) i ( n i ) f ( i ) g(n)=\sum\limits_{i=0}^n(-1)^i\binom{n}{i}f(i) g(n)=i=0n(1)i(in)f(i)

证明:

∑ i = 0 n ( − 1 ) i ( n i ) f ( i ) = ∑ i = 0 n ( − 1 ) i ( n i ) ∑ j = 0 i ( − 1 ) j ( i j ) g ( j ) = ∑ j = 0 n ( − 1 ) j g ( j ) ∑ i = j n ( − 1 ) i ( n i ) ( i j ) = ∑ j = 0 n g ( j ) ( n j ) ∑ i = j n ( − 1 ) i − j ( n − j i − j ) = ∑ j = 0 n g ( j ) ( n j ) ( 1 − 1 ) n − j \sum\limits_{i=0}^n(-1)^i\binom{n}{i}f(i)=\sum\limits_{i=0}^{n}(-1)^i\binom{n}{i}\sum\limits_{j=0}^i(-1)^j\binom{i}{j}g(j)=\sum\limits_{j=0}^n(-1)^jg(j)\sum\limits_{i=j}^n(-1)^i\binom{n}{i}\binom{i}{j}=\sum_{j=0}^ng(j)\binom{n}{j} \sum_{i=j}^n(-1)^{i-j}\binom{n-j}{i-j}=\sum\limits_{j=0}^ng(j)\binom{n}{j}(1-1)^{n-j} i=0n(1)i(in)f(i)=i=0n(1)i(in)j=0i(1)j(ji)g(j)=j=0n(1)jg(j)i=jn(1)i(in)(ji)=j=0ng(j)(jn)i=jn(1)ij(ijnj)=j=0ng(j)(jn)(11)nj
n = j n=j n=j时, ( 1 − 1 ) n − j (1-1)^{n-j} (11)nj为1, 其余值都为 0 0 0.
此时, ∑ j = 0 n g ( j ) ( 1 − 1 ) n − j = g ( n ) \sum_{j=0}^ng(j)(1-1)^{n-j}=g(n) j=0ng(j)(11)nj=g(n)
得证.

在上述过程中,用了一个组合恒等式——范德蒙德恒等式:
( n i ) ( i j ) = ( n j ) ( n − j i − j ) \binom{n}{i} \binom{i}{j} = \binom{n}{j} \binom{n-j}{i-j} (in)(ji)=(jn)(ijnj)
从组合意义去理解, n n n中选 i i i,再从 i i i中选 j j j个,即有 j j j个笑到了最后,有 i − j i-j ij只过了第一轮。所以,它等于从 n n n中选 j j j个最终胜出者,再从 n − j n-j nj中选 ( i − j ) (i-j) (ij)个。

通过数学推导也可以证明如下:
( n i ) ( i j ) = n ! i ! ( n − i ) ! × i ! ( i − j ) ! j ! = n ! ( n − j ) ! ( n − i ) ! × ( n − j ) ! ( i − j ) ! j ! = n ! ( n − j ) ! j ! × ( n − j ) ! ( i − j ) ! ( n − i ) ! = ( n j ) ( n − j i − j ) \begin{aligned} \binom{n}{i}\binom{i}{j} &= \frac{n!}{i!(n-i)!}\times \frac{i!}{(i-j)!j!}=\frac{n!}{(n-j)!(n-i)!}\times \frac{(n-j)!}{(i-j)!j!}\\ &=\frac{n!}{(n-j)!j!}\times \frac{(n-j)!}{(i-j)!(n-i)!} \\ &=\binom{n}{j} \binom{n-j}{i-j} \end{aligned} (in)(ji)=i!(ni)!n!×(ij)!j!i!=nj)!(ni)!n!×(ij)!j!(nj)!=nj)!j!n!×(ij)!(ni)!(nj)!=(jn)(ijnj)

形式二:

f ( n ) = ∑ i = 0 n ( n i ) g ( i ) f(n)=\sum\limits_{i=0}^n\binom{n}{i}g(i) f(n)=i=0n(in)g(i),有:
g ( n ) = ∑ i = 0 n ( − 1 ) n − i ( n i ) f ( i ) g(n)=\sum_{i=0}^n(-1)^{n-i}\binom{n}{i}f(i) g(n)=i=0n(1)ni(in)f(i).
h ( i ) = ( − 1 ) i g ( i ) h(i)=(-1)^ig(i) h(i)=(1)ig(i), 则形式一可以写成:
f ( n ) = ∑ i = 0 n ( n i ) h ( i ) f(n)=\sum_{i=0}^n\binom{n}{i}h(i) f(n)=i=0n(in)h(i),则有:
( − 1 ) n h ( n ) = ∑ i = 0 n ( − 1 ) i ( n i ) f ( i ) (-1)^nh(n)=\sum_{i=0}^n(-1)^i\binom{n}{i}f(i) (1)nh(n)=i=0n(1)i(in)f(i)

即:
若有 f ( n ) = ∑ i = 0 n ( n i ) h ( i ) f(n)=\sum_{i=0}^n\binom{n}{i}h(i) f(n)=i=0n(in)h(i)
则有: h ( n ) = ∑ i = 0 n ( − 1 ) n − 1 ( n i ) f ( i ) h(n)=\sum_{i=0}^n(-1)^{n-1}\binom{n}{i}f(i) h(n)=i=0n(1)n1(in)f(i)

整理即得到形式二。

形式三:

f ( n ) = ∑ i = m n ( n i ) g ( i ) f(n)=\sum\limits_{i=m}^n\binom{n}{i}g(i) f(n)=i=mn(in)g(i), 则有:
g ( n ) = ∑ i = m n ( − 1 ) n − i ( n i ) f ( i ) g(n)=\sum\limits_{i=m}^n(-1)^{n-i}\binom{n}{i}f(i) g(n)=i=mn(1)ni(in)f(i).

证明同形式一。
证明如下:
∑ i = m n ( − 1 ) n − i ( n i ) f ( i ) = ∑ i = m n ( − 1 ) n − i ( n i ) ∑ j = m i ( i j ) g ( j ) = ∑ j = m n g ( j ) ∑ i = j n ( − 1 ) n − i ( n i ) ( i j ) = ∑ j = m n g ( j ) ( n j ) ∑ i = j n ( − 1 ) n − i ( n − j i − j ) = ∑ j = m n ( n j ) g ( j ) ( 1 − 1 ) n − j = g ( n ) \sum\limits_{i=m}^n(-1)^{n-i}\binom{n}{i}f(i)=\sum\limits_{i=m}^n(-1)^{n-i}\binom{n}{i}\sum\limits_{j=m}^i\binom{i}{j}g(j)=\sum\limits_{j=m}^ng(j)\sum\limits_{i=j}^n(-1)^{n-i}\binom{n}{i}\binom{i}{j}=\sum\limits_{j=m}^ng(j)\binom{n}{j}\sum\limits_{i=j}^n(-1)^{n-i}\binom{n-j}{i-j}=\sum\limits_{j=m}^n\binom{n}{j}g(j)(1-1)^{n-j}=g(n) i=mn(1)ni(in)f(i)=i=mn(1)ni(in)j=mi(ji)g(j)=j=mng(j)i=jn(1)ni(in)(ji)=j=mng(j)(jn)i=jn(1)ni(ijnj)=j=mn(jn)g(j)(11)nj=g(n)

形式四:

f ( n ) = ∑ i = n m ( i n ) g ( i ) f(n)=\sum\limits_{i=n}^m\binom{i}{n}g(i) f(n)=i=nm(ni)g(i), 有:
g ( n ) = ∑ i = n m ( − 1 ) i − n ( i n ) f ( i ) g(n)=\sum\limits_{i=n}^m(-1)^{i-n}\binom{i}{n}f(i) g(n)=i=nm(1)in(ni)f(i)
证明同形式三。

例题一:求错位排列

有一个由 n n n个不同的字符组成的序列,现在打乱它,使得每个字符均不在它正确的位置上,问有多少种排列方法?
分析一:容斥原理
我们可以直接通过容斥原理写出:
a n s = ∑ i = 0 n ( − 1 ) i ( n i ) ( n − i ) ! (1) ans=\sum_{i=0}^n(-1)^i\binom{n}{i}(n-i)! \tag{1} ans=i=0n(1)i(in)(ni)!(1)
解释一下,错排方案数等于全排列减去有 1 1 1张牌在正确位置的数量,再 2 2 2张牌在正确位置的数量,再减去 3 3 3张牌在正确位置的数量, … \dots ,最后加上 ( − 1 ) n (-1)^n (1)n乘以n张牌在正确位置的数量。

分析二:二项式反演
设长度为 n n n的错位排列为 f ( n ) f(n) f(n) n n n张牌的全排列为 n ! n! n!.
显然有 n ! = ∑ i = 0 n ( n i ) f ( i ) n!=\sum_{i=0}^n\binom{n}{i}f(i) n!=i=0n(in)f(i).
根据二项式反演(形式二),得:
f ( n ) = ∑ i = 0 n ( − 1 ) n − i ( n i ) i ! (2) f(n)=\sum_{i=0}^n(-1)^{n-i}\binom{n}{i}i! \tag{2} f(n)=i=0n(1)ni(in)i!(2)

( 1 ) (1) (1) ( 2 ) (2) (2)是等价的。

分析三:二项式反演(形式
n n n张牌中,钦定有 i i i张牌在正确位置上的排列数为 f ( i ) f(i) f(i), 而恰好有 i i i张牌在正确位置上的
排列数为 g ( i ) g(i) g(i).
则有 f ( i ) = ∑ j = i n ( j i ) g ( j ) (3) f(i)=\sum_{j=i}^n\binom{j}{i}g(j) \tag{3} f(i)=j=in(ij)g(j)(3)
注意:此处 f ( i ) f(i) f(i)钦定 i i i张在正确位置,指包含所有钦定 i i i张的情况,即 f ( i ) = ( n i ) ( n − i ) ! f(i)=\binom{n}{i}(n-i)! f(i)=(in)(ni)!.
其中有 j ( j > i ) j(j>i) j(j>i)张在正确位置的情形,都是会重复计算的,计算的次数正好是 ( j i ) \binom{j}{i} (ij),这也是式 ( 3 ) (3) (3)的右边出现 ( j i ) \binom{j}{i} (ij)的原因。

将式 ( 3 ) (3) (3)二项式反演(形式四),可得:
g ( i ) = ∑ j = i n ( − 1 ) j − i ( j i ) f ( j ) = ∑ j = i n ( − 1 ) j − i ( j i ) ( n j ) ( n − j ) ! (4) g(i)=\sum_{j=i}^n(-1)^{j-i}\binom{j}{i}f(j) =\sum_{j=i}^n(-1)^{j-i}\binom{j}{i}\binom{n}{j}(n-j)! \tag{4} g(i)=j=in(1)ji(ij)f(j)=j=in(1)ji(ij)(jn)(nj)!(4)

长度为 n n n的错排,即恰好有 0 0 0个字符在正确位置上的排列数,即为: g ( 0 ) = ∑ j = 0 n ( − 1 ) j ( j 0 ) ( n j ) ( n − j ) ! = ∑ j = 0 n ( − 1 ) j ( n j ) ( n − j ) ! (5) g(0)=\sum_{j=0}^n(-1)^j\binom{j}{0}\binom{n}{j}(n-j)! = \sum_{j=0}^n(-1)^j\binom{n}{j}(n-j)!\tag{5} g(0)=j=0n(1)j(0j)(jn)(nj)!=j=0n(1)j(jn)(nj)!(5)

( 5 ) (5) (5)和式 ( 1 ) (1) (1)是完全等价的。

一个错误的思路
这里开始走了点弯路。记录如下:
n n n张牌中有 i i i张在正确位置上的方案数为 f ( i ) f(i) f(i), n n n张牌的全排列为 n ! n! n!.
显然有: n ! = ∑ i = 0 n ( n i ) f ( i ) (A) n!=\sum_{i=0}^n\binom{n}{i}f(i) \tag{A} n!=i=0n(in)f(i)(A).
根据二项式反演,得:
f ( n ) = ∑ i = 0 n ( − 1 ) n − i ( n i ) i ! (B) f(n)=\sum_{i=0}^n(-1)^{n-i}\binom{n}{i}i! \tag{B} f(n)=i=0n(1)ni(in)i!(B)

( B ) (B) (B)这个式子和式 ( 2 ) (2) (2)是完全一样的。
但接下来就有有点神奇了:
f ( 0 ) f(0) f(0)应该是我们要求的错位排列,把 n = 0 n=0 n=0代入:
则有 f ( 0 ) = ∑ i = 0 0 ( − 1 ) − i ( 0 0 ) 0 ! f(0)=\sum_{i=0}^0(-1)^{-i}\binom{0}{0}0! f(0)=i=00(1)i(00)0!
这个结果完全不对。
那么错在哪里呢?
f ( i ) f(i) f(i)表示是有问题的,它表示 n n n张牌中有 i i i张在正确位置上的方案数,它与 n , i n,i n,i都有关系,所以要表示为 f ( n , i ) f(n,i) f(n,i),而不能表示为 f ( i ) f(i) f(i)
那为什么在式 ( 3 ) (3) (3)中, f ( i ) , g ( i ) f(i),g(i) f(i),g(i)也与 n n n有关,就能写成 f ( i ) , g ( i ) f(i),g(i) f(i),g(i)呢?
其实,是因为在式 ( 3 ) (3) (3)中, n n n是常量,而在式 A A A中, n n n是变量。
只有当 n n n为常量时,我们才能可以省掉它,写成 f ( i ) f(i) f(i).

例题二:洛谷P4859 已经没有什么好害怕的了

题目大意

有两个长度为 n n n的序列 a , b a,b a,b, 将 a a a序列与 b b b序列配对,使得 a > b a>b a>b的配对数量恰好比 a < b a<b a<b的配对数量多 k k k对。问有多少种配对方案?

分析

先将序列按由小到大排序。
问题要求恰好多k对,我们可以先求“a>b”的数量至少有多少对的方案。
d p i , j dp_{i,j} dpi,j表示排序后 a a a序列的前缀 i i i j j j个配对满足“a>b”的配对方案数。
则根据 a i a_i ai是否配对,可以得到如下转移方程:
d p i , j = d p i − 1 , j + d p i − 1 , j − 1 × ( c n t − j + 1 ) dp_{i,j}=dp_{i-1,j}+dp_{i-1,j-1}\times (cnt-j+1) dpi,j=dpi1,j+dpi1,j1×(cntj+1)
其中 c n t cnt cnt表示b序列中小于 a i a_i ai的字符数,这可以双指针扫描求出。

f i f_i fi表示恰好有 i i i个配对满足"a>b", g i g_i gi表示至少有 i i i个配对满足“a>b”.
显然有: g i = ∑ j = i n ( j i ) f j g_i=\sum_{j=i}^n\binom{j}{i}f_j gi=j=in(ij)fj

根据二项式反演(形式四),则有:
f i = ∑ j = i n ( − 1 ) j − i ( j i ) g ( j ) f_i=\sum\limits_{j=i}^n(-1)^{j-i}\binom{j}{i}g(j) fi=j=in(1)ji(ij)g(j)

此处的 g ( j ) g(j) g(j)即为前面的 d p n , j × ( n − j ) ! dp_{n,j} \times (n-j)! dpn,j×(nj)!.

#include <bits/stdc++.h>
using namespace std;
#define maxn 2005
#define ll long long int
#define mod 1000000009
ll dp[maxn][maxn];
ll a[maxn], b[maxn], fac[maxn], recfac[maxn];
ll c[maxn];
ll ans;
int n, k;
ll qpow(ll a, ll b){
    ll res = 1;
    while(b){
        if(b & 1) res = (res * a) % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}


ll C(int x, int y){
    if(x < y)return 0;
    if(y == 0) return 1;
    if(x == y) return 1;
    return fac[x] * recfac[y] % mod * recfac[x - y] % mod;
}

int main(){
    scanf("%d %d", &n, &k);
    fac[0] = 1;
    for(int i = 1; i <= n; i++)fac[i] = fac[i - 1] * i % mod;
    recfac[n] = qpow(fac[n], mod - 2);
    for(int i = n - 1; i > 1; i--) recfac[i] = recfac[i + 1] * (i + 1) % mod;
    recfac[1] = 1;
    recfac[0] = 1;
   
    for(int i = 1; i <= n; i++)
        cin >> a[i];

    for(int i = 1; i <= n; i++)
        cin >> b[i];

    sort(a + 1, a + n + 1);
    sort(b + 1, b + n + 1);
    int cnt = 0;
    dp[0][0] = 1;
    for(int i = 1, j = 1; i <= n; i++){
        while(j <= n && b[j] < a[i]) j++;
        dp[i][0] = 1;
        for(int p = 1; p <= i && p < j; p++){
            dp[i][p] = (dp[i - 1][p] + dp[i - 1][p - 1] *(j - p)) % mod;
        }
    }
   
    for(int i = 0; i <= n; i++) dp[n][i] = (dp[n][i] * fac[n - i]) % mod;
    if((n - k) % 2) {printf("0\n");return 0;}
    int t = (n + k) / 2;
    int flg = 1;
    for(int i = t; i <= n; i++){
        ans = (ans + flg * C(i, t)*dp[n][i]) % mod;
        flg = -1 * flg;
    }

    printf("%lld\n", (ans + mod)% mod);
    return 0;
}

例题二: 集合计数

题目大意:

n n n个元素组成的集合,一共有 2 n − 1 2^n-1 2n1个非空子集。求选择若干个子集,使得它们的交集刚好包含 k k k个元素的所有方案数。

解法一:

本题其实可以通过容斥原理直接列出式子:
a n s = ∑ j = k n ( − 1 ) j − k ( j k ) ( n j ) ( 2 2 n − j − 1 ) ans=\sum_{j=k}^n(-1)^{j-k}\binom{j}{k}\binom{n}{j}(2^{2^{n-j}}-1) ans=j=kn(1)jk(kj)(jn)(22nj1)

解法二:

f i f_i fi表示至少有 i i i个元素出现在交集中的方案数之和, g i g_i gi表示恰好有 i i i个元素出现在交集中的方案数。
显然有: f i = ∑ j = i n ( j i ) g j = ( n i ) ( 2 2 n − i − 1 ) f_i=\sum_{j=i}^n\binom{j}{i}g_j=\binom{n}{i}(2^{2^{n-i}}-1) fi=j=in(ij)gj=(in)(22ni1)
根据二项式反演(形式四),
g i = ∑ j = i n ( − 1 ) j − i ( j i ) f j = ∑ j = i n ( − 1 ) j − i ( j i ) ( n j ) ( 2 2 n − j − 1 ) g_i=\sum_{j=i}^n(-1)^{j-i}\binom{j}{i}f_j=\sum_{j=i}^n(-1)^{j-i}\binom{j}{i}\binom{n}{j}(2^{2^{n-j}}-1) gi=j=in(1)ji(ij)fj=j=in(1)ji(ij)(jn)(22nj1)

这与解法一是等价的。

例题三:NOI Online 游戏 洛谷6478

题目大意:一棵无根树,有 n = 2 m n=2m n=2m个节点,有两人玩一个树上游戏。两人各拥有 m m m个点,共玩 m m m个回合。每一回合,每人从自己拥有的且之前未被选过的点中随机选择一个,如果某个回合,一个玩家选的点是另一个玩家在该回合中选的点的子树中,则该回合前者失败,其他情况都视为平局。问 m m m个回合中,有 k ( 1 ≤ k ≤ m ) k(1 \leq k \leq m) k(1km)非平局的情况数。 两种情况不同,当且仅当两种情况中各存在一个回合,其中一个玩家选择了相同的点,而另一个玩家选择了不同的点。

分析

f ( i ) f(i) f(i)表示至少有 i i i个非平局的方案数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值