容斥原理相关

一.补集转化.

补集转化:对于两个集合 U , S U,S U,S满足 S ⊆ U S\subseteq U SU,我们有:
∣ S ∣ = ∣ U ∣ − ∣ U − S ∣ |S|=|U|-|U-S| S=UUS

根据补集的定义即可得到上式.

对应到计数问题中,当我们计算满足某个条件的方案数时,可以先计算出总共的方案数,再计算出不满足这个条件的方案数,前者减去后者就是原问题的答案.


二.容斥原理.

考虑对于两个集合 A , B A,B A,B,它们的并的大小和交的大小之间的关系式怎么样的?显然有关系:
∣ A ∪ B ∣ = ∣ A ∣ + ∣ B ∣ − ∣ A ∩ B ∣ |A \cup B|=|A|+|B|-|A\cap B| AB=A+BAB

那么如果是三个集合 A , B , C A,B,C A,B,C时的情况呢?显然有关系:
∣ A ∪ B ∪ C ∣ = ∣ A ∣ + ∣ B ∣ + ∣ C ∣ − ∣ A ∩ B ∣ − ∣ A ∩ C ∣ − ∣ B ∩ C ∣ + ∣ A ∩ B ∩ C ∣ |A\cup B\cup C|=|A|+|B|+|C|-|A\cap B|-|A\cap C|-|B\cap C|+|A\cap B\cap C| ABC=A+B+CABACBC+ABC

以此类推下去,我们会得到一个 n n n个集合 S 1 , S 2 , S 3 , ⋯   , S n S_1,S_2,S_3,\cdots,S_n S1,S2,S3,,Sn之间的关系式:
∣ ⋃ i = 1 n S i ∣ = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 ∣ ⋂ i ∈ T S i ∣ \left|\bigcup_{i=1}^{n}S_i\right|=\sum_{T\subseteq [n]}(-1)^{|T|-1}\left|\bigcap_{i\in T}S_i\right| i=1nSi=T[n](1)T1iTSi

但是这个关系式是否正确呢?答案是正确的,这个式子被称为容斥原理.

证明:
考虑数学归纳法:
1.当 n = 1 , 2 n=1,2 n=1,2时,定理显然成立.
2.当 n > 2 n>2 n>2时,若在 k < n k<n k<n时定理成立,则 k = n k=n k=n时有:
∣ ⋃ i = 1 k S i ∣ = ∣ ( ⋃ i = 1 k − 1 S i ) ∪ S k ∣ = ∣ ⋃ i = 1 k − 1 S i ∣ + ∣ S k ∣ − ∣ ( ⋃ i = 1 k − 1 S i ) ∩ S k ∣ = ∣ ⋃ i = 1 k − 1 S i ∣ + ∣ S k ∣ − ∣ ⋃ i = 1 k − 1 ( S i ∩ S k ) ∣ = ∑ T ⊆ [ k − 1 ] ( − 1 ) ∣ T ∣ − 1 ∣ ⋂ i ∈ T S i ∣ + ∣ S k ∣ − ∑ T ⊆ [ k − 1 ] ( − 1 ) ∣ T ∣ − 1 ∣ ( ⋂ i ∈ T S i ) ∩ S k ∣ = ∑ T ⊆ [ k ] ( − 1 ) ∣ T ∣ − 1 ∣ ⋂ i ∈ T S i ∣ \left|\bigcup_{i=1}^{k}S_i\right|=\left|\left(\bigcup_{i=1}^{k-1}S_i\right)\cup S_k\right|\\ =\left|\bigcup_{i=1}^{k-1}S_i\right|+|S_k|-\left|\left(\bigcup_{i=1}^{k-1}S_i\right)\cap S_k\right|\\ =\left|\bigcup_{i=1}^{k-1}S_i\right|+|S_k|-\left|\bigcup_{i=1}^{k-1}(S_i\cap S_k)\right|\\ =\sum_{T\subseteq [k-1]}(-1)^{|T|-1}\left|\bigcap_{i\in T}S_i\right|+|S_k|-\sum_{T\subseteq [k-1]}(-1)^{|T|-1}\left|\left(\bigcap_{i\in T}S_i\right)\cap S_k\right|\\ =\sum_{T\subseteq [k]}(-1)^{|T|-1}\left|\bigcap_{i\in T}S_i\right| i=1kSi=(i=1k1Si)Sk=i=1k1Si+Sk(i=1k1Si)Sk=i=1k1Si+Ski=1k1(SiSk)=T[k1](1)T1iTSi+SkT[k1](1)T1(iTSi)Sk=T[k](1)T1iTSi

证毕.

其实,通过类似的证明方法,我们还可以得到一种容斥原理的变形
∣ ⋂ i = 1 n S i ∣ = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 ∣ ⋃ i ∈ T S i ∣ \left|\bigcap_{i=1}^{n}S_i\right|=\sum_{T\subseteq [n]}(-1)^{|T|-1}\left|\bigcup_{i\in T}S_i\right| i=1nSi=T[n](1)T1iTSi



三.广义容斥原理.

广义容斥原理:对于两个函数定义域为集合的函数 f , g f,g f,g有:
f ( S 1 ) = ∑ S 2 ⊆ S 1 g ( S 2 ) ⇔ g ( S 1 ) = ∑ S 2 ⊆ S 1 ( − 1 ) ∣ S 1 ∣ − ∣ S 2 ∣ f ( S 2 ) f(S_1)=\sum_{S_2\subseteq S_1}g(S_2)\Leftrightarrow g(S_1)=\sum_{S_2\subseteq S_1}(-1)^{|S_1|-|S_2|}f(S_2) f(S1)=S2S1g(S2)g(S1)=S2S1(1)S1S2f(S2)

考虑每一个集合的贡献,就会发现这个形式就是容斥原理的推广形式.

但是我们并不能直接确定这个形式就是正确的,所以还是需要证明一下.

证明:
将第二个式子带入第一个式子中得到:
f ( S 1 ) = ∑ S 2 ⊆ S 1 ∑ S 3 ⊆ S 2 ( − 1 ) ∣ S 2 ∣ − ∣ S 3 ∣ f ( S 3 ) = ∑ S 2 ⊆ S 1 f ( S 2 ) ∑ S 2 ⊆ S 3 ⊆ S 1 ( − 1 ) ∣ S 3 ∣ − ∣ S 2 ∣ = ∑ S 2 ⊆ S 1 f ( S 2 ) ∑ i = 0 ∣ S 1 ∣ − ∣ S 2 ∣ ( − 1 ) i ( ∣ S 1 ∣ − ∣ S 2 ∣ i ) = ∑ S 2 ⊆ S 1 f ( S 2 ) [ ∣ S 1 ∣ = ∣ S 2 ∣ ] = f ( S 2 ) f(S_1)=\sum_{S_2\subseteq S_1}\sum_{S_3\subseteq S_2}(-1)^{|S_2|-|S_3|}f(S_3)\\ =\sum_{S_2\subseteq S_1}f(S_2)\sum_{S_2\subseteq S_3\subseteq S_1}(-1)^{|S_3|-|S_2|}\\ =\sum_{S_2\subseteq S_1}f(S_2)\sum_{i=0}^{|S_1|-|S_2|}(-1)^{i}\binom{|S_1|-|S_2|}{i}\\ =\sum_{S_2\subseteq S_1}f(S_2)[|S_1|=|S_2|]\\ =f(S_2) f(S1)=S2S1S3S2(1)S2S3f(S3)=S2S1f(S2)S2S3S1(1)S3S2=S2S1f(S2)i=0S1S2(1)i(iS1S2)=S2S1f(S2)[S1=S2]=f(S2)

证毕.

本质上用偏序集构造的证明与这个证明是一样的,这里不再赘述.

可以通过反演原理推出其它的一些形式.


四.广义容斥原理的计算与快速Mobius变换.

广义容斥原理中主要有两个式子需要计算:
f ( S 1 ) = ∑ S 2 ⊆ S 1 g ( S 2 ) f ( S 1 ) = ∑ S 2 ⊆ S 1 ( − 1 ) ∣ S 1 ∣ − ∣ S 2 ∣ g ( S 2 ) f(S_1)=\sum_{S_2\subseteq S_1}g(S_2)\\ f(S_1)=\sum_{S_2\subseteq S_1}(-1)^{|S_1|-|S_2|}g(S_2) f(S1)=S2S1g(S2)f(S1)=S2S1(1)S1S2g(S2)

当我们看到这三个式子的时候,发现只会用 O ( 3 n ) O(3^{n}) O(3n)的算法枚举子集求出所有 f ( S ) f(S) f(S),然而这个复杂度并不优秀.

能否通过一些方法来优化呢?当然是可以的.

我们考虑一个贡献图,例如有三个物品时的贡献图为:
在这里插入图片描述
其中 S 1 S_1 S1能够到达 S 2 S_2 S2表示 S 1 S_1 S1会对 S 2 S_2 S2做出一次贡献.

为了让复杂度低于 O ( 3 n ) O(3^{n}) O(3n),我们考虑按照上图中的分层进行逐层累加,但这样会有算重的部分.

此时我们不妨确定一个字典序(比如按照集合中元素的标号确定的字典序),每次让 S 1 S_1 S1 S 2 S_2 S2转移时通过字典序最小的路径,这样就可以保证贡献不会重复了.例如要把 000 000 000贡献到 101 101 101上时,我们只通过先加入物品 0 0 0再加入物品 2 2 2来贡献而不是先 2 2 2 0 0 0.

具体来说,我们枚举当前往路径字典序中加入的元素 i = 1 → n i=1\rightarrow n i=1n,并进行所有与它相关的转移就可以了.

时间复杂度 O ( 2 n n ) O(2^{n}n) O(2nn).

代码如下:

void FMT(int *a,int n){
  for (int i=0;i<n;++i)
    for (int g=0;g<1<<n;++g)
      if (g>>i&1^1) a[g|1<<i]+=a[g];
}

然后,通过类似的方式,我们完全可以写出另外一个式子的代码:

void IFMT(int *a,int n){
  for (int i=0;i<n;++i)
    for (int g=0;g<1<<n;++g)
      if (g>>i&1^1) a[g|1<<i]-=a[g];
}

与FFT类似的,FMT与IFMT也可以写到一起:

void FMT(int *a,int n,int t){
  for (int i=0;i<n;++i)
    for (int g=0;g<1<<n;++g)
      if (g>>i&1^1) a[g|1<<i]+=(t?-1:1)*a[g];
}



五.二项式反演.

对于上面的广义容斥原理,假设有:
∣ S 1 ∣ = ∣ S 2 ∣ ⇒ f ( S 1 ) = f ( S 2 ) ∧ g ( S 1 ) = g ( S 2 ) |S_1|=|S_2|\Rightarrow f(S_1)=f(S_2)\wedge g(S_1)=g(S_2) S1=S2f(S1)=f(S2)g(S1)=g(S2)

那么我们设 f ( i ) f(i) f(i)表示为 ∣ S ∣ = i |S|=i S=i时的 f ( S ) f(S) f(S) g g g同理,可以得到:
f ( i ) = ∑ j = 0 i ( i j ) g ( j ) ⇔ g ( i ) = ∑ j = 0 i ( − 1 ) i − j ( i j ) f ( j ) f(i)=\sum_{j=0}^{i}\binom{i}{j}g(j)\Leftrightarrow g(i)=\sum_{j=0}^{i}(-1)^{i-j}\binom{i}{j}f(j) f(i)=j=0i(ji)g(j)g(i)=j=0i(1)ij(ji)f(j)

我们把这个式子称为二项式反演.

通过反演原理,不难推出其它几种形式.


六.并-交反演.

这个名字是本人瞎取的不要当真…

这个反演与容斥原理的形式非常像,具体来说就是这样两个式子:
f ( ⋃ i = 1 n S i ) = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ f ( ⋂ i ∈ T S i ) ⇔ f ( ⋂ i = 1 n S i ) = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ f ( ⋃ i ∈ T S i ) f ( ⋃ i = 1 n S i ) = ∏ T ⊆ [ n ] f ( − 1 ) ∣ T ∣ ( ⋂ i ∈ T S i ) ⇔ f ( ⋂ i = 1 n S i ) = ∏ T ⊆ [ n ] f ( − 1 ) ∣ T ∣ ( ⋃ i ∈ T S i ) f\left(\bigcup_{i=1}^{n}S_i\right)=\sum_{T\subseteq [n]}(-1)^{|T|}f\left(\bigcap_{i\in T}S_i\right)\Leftrightarrow f\left(\bigcap_{i=1}^{n}S_i\right)=\sum_{T\subseteq [n]}(-1)^{|T|}f\left(\bigcup_{i\in T}S_i\right)\\ f\left(\bigcup_{i=1}^{n}S_i\right)=\prod_{T\subseteq [n]}f^{(-1)^{|T|}}\left(\bigcap_{i\in T}S_i\right)\Leftrightarrow f\left(\bigcap_{i=1}^{n}S_i\right)=\prod_{T\subseteq [n]}f^{(-1)^{|T|}}\left(\bigcup_{i\in T}S_i\right)\\ f(i=1nSi)=T[n](1)Tf(iTSi)f(i=1nSi)=T[n](1)Tf(iTSi)f(i=1nSi)=T[n]f(1)T(iTSi)f(i=1nSi)=T[n]f(1)T(iTSi)

容易发现这就是广义容斥原理的一个特例,故不再证明.

这两个式子在多重集意义下仍然是成立的.


七.min-max反演.

min-max反演算是上面并-交反演的一个应用,它的作用是用反演实现一个集合内元素的min和max之间的转化.

我们将每一个整数 n n n看成一个集合 S ( n ) = { 1 , 2 , 3 , . . . , n } S(n)=\{1,2,3,...,n\} S(n)={1,2,3,...,n},那么集合 S S S对应的原数就是 max ⁡ { S } \max\{S\} max{S}.

显然我们有:
min ⁡ i = 1 n { a i } = max ⁡ ( ⋂ i = 1 n S ( a i ) ) max ⁡ i = 1 n { a i } = max ⁡ ( ⋃ i = 1 n S ( a i ) ) \min_{i=1}^{n}\{a_i\}=\max\left( \bigcap_{i=1}^{n} S(a_i)\right)\\ \max_{i=1}^{n}\{a_i\}=\max\left( \bigcup_{i=1}^{n} S(a_i) \right) i=1minn{ai}=max(i=1nS(ai))i=1maxn{ai}=max(i=1nS(ai))

定义 max ⁡ ( ∅ ) = 0 \max(\empty)=0 max()=0.

然后就可以推导:
max ⁡ i = 1 n { a i } = max ⁡ { ⋃ i = 1 n S ( a i ) } = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 max ⁡ { ⋂ i = 1 m S ( a i ) } = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 min ⁡ i ∈ T { a i } \max_{i=1}^{n}\{a_i\}=\max\left\{\bigcup_{i=1}^{n}S(a_i)\right\}\\ =\sum_{T\subseteq [n]}(-1)^{|T|-1}\max\left\{ \bigcap_{i=1}^{m}S(a_i) \right\}\\ =\sum_{T\subseteq [n]}(-1)^{|T|-1}\min_{i\in T}\{a_i\} i=1maxn{ai}=max{i=1nS(ai)}=T[n](1)T1max{i=1mS(ai)}=T[n](1)T1iTmin{ai}

同理有:
min ⁡ i = 1 n { a i } = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 max ⁡ i ∈ T { a i } \min_{i=1}^{n}\{a_i\}=\sum_{T\subseteq [n]}(-1)^{|T|-1}\max_{i\in T}\{a_i\} i=1minn{ai}=T[n](1)T1iTmax{ai}

那么我们得到了一个反演,称之为min-max反演
max ⁡ i = 1 n { a i } = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 min ⁡ i ∈ T { a i } ⇔ min ⁡ i = 1 n { a i } = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 max ⁡ i ∈ T { a i } \max_{i=1}^{n}\{a_i\}=\sum_{T\subseteq [n]}(-1)^{|T|-1}\min_{i\in T}\{a_i\}\Leftrightarrow \min_{i=1}^{n}\{a_i\}=\sum_{T\subseteq [n]}(-1)^{|T|-1}\max_{i\in T}\{a_i\} i=1maxn{ai}=T[n](1)T1iTmin{ai}i=1minn{ai}=T[n](1)T1iTmax{ai}

根据期望的线性性,这个式子在期望的意义下仍然成立,即:
E ( max ⁡ i = 1 n { a i } ) = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 E ( min ⁡ i ∈ T { a i } ) ⇔ E ( min ⁡ i = 1 n { a i } ) = ∑ T ⊆ [ n ] ( − 1 ) ∣ T ∣ − 1 E ( max ⁡ i ∈ T { a i } ) E\left(\max_{i=1}^{n}\{a_i\}\right)=\sum_{T\subseteq [n]}(-1)^{|T|-1}E\left(\min_{i\in T}\{a_i\}\right)\Leftrightarrow E\left(\min_{i=1}^{n}\{a_i\}\right)=\sum_{T\subseteq [n]}(-1)^{|T|-1}E\left(\max_{i\in T}\{a_i\}\right) E(i=1maxn{ai})=T[n](1)T1E(iTmin{ai})E(i=1minn{ai})=T[n](1)T1E(iTmax{ai})



八.gcd-lcm反演.

与min-max反演类似,gcd-lcm反演是通过多重集的并-交反演来推导出一个集合的gcd和lcm之间的反演关系式的.

我们考虑把一个数 n n n唯一分解成素因数,记这个素因数多重集为 S ( n ) S(n) S(n).

然后我们定义函数 f ( S ) f(S) f(S)表示将 S S S内的所有数的乘积,即 f ( S ) = ∏ i ∈ S i f(S)=\prod_{i\in S}i f(S)=iSi.

显然我们有:
g c d i = 1 n ( a i ) = f ( ⋂ i = 1 n S ( a i ) ) l c m i = 1 n ( a i ) = f ( ⋃ i = 1 n S ( a i ) ) gcd_{i=1}^{n}(a_i)=f\left( \bigcap_{i=1}^{n}S(a_i) \right)\\ lcm_{i=1}^{n}(a_i)=f\left( \bigcup_{i=1}^{n}S(a_i) \right) gcdi=1n(ai)=f(i=1nS(ai))lcmi=1n(ai)=f(i=1nS(ai))

定义 max ⁡ ( ∅ ) = 1 \max(\empty)=1 max()=1.

开始推导:
l c m i = 1 n { a i } = f ( ⋃ i = 1 n S ( a i ) ) = ∏ T ⊆ [ n ] f ( − 1 ) ∣ T ∣ − 1 ( ⋂ i = 1 n S ( a i ) ) = ∏ T ⊆ [ n ] g c d i ∈ T ( − 1 ) ∣ T ∣ − 1 ( a i ) lcm_{i=1}^{n}\{a_i\}=f\left(\bigcup_{i=1}^{n} S(a_i)\right)\\ =\prod_{T\subseteq [n]}f^{(-1)^{|T|-1}}\left(\bigcap_{i=1}^{n}S(a_i)\right)\\ =\prod_{T\subseteq[n]}gcd^{(-1)^{|T|-1}}_{i\in T}(a_i) lcmi=1n{ai}=f(i=1nS(ai))=T[n]f(1)T1(i=1nS(ai))=T[n]gcdiT(1)T1(ai)

反过来也是一样的,所以gcd-lcm反演即:
l c m i = 1 n { a i } = ∏ T ⊆ [ n ] g c d i ∈ T ( − 1 ) ∣ T ∣ − 1 ( a i ) ⇔ g c d i = 1 n { a i } = ∏ T ⊆ [ n ] l c m i ∈ T ( − 1 ) ∣ T ∣ − 1 ( a i ) lcm_{i=1}^{n}\{a_i\}=\prod_{T\subseteq[n]}gcd^{(-1)^{|T|-1}}_{i\in T}(a_i)\Leftrightarrow gcd_{i=1}^{n}\{a_i\}=\prod_{T\subseteq[n]}lcm^{(-1)^{|T|-1}}_{i\in T}(a_i) lcmi=1n{ai}=T[n]gcdiT(1)T1(ai)gcdi=1n{ai}=T[n]lcmiT(1)T1(ai)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值