一.补集转化.
补集转化:对于两个集合
U
,
S
U,S
U,S满足
S
⊆
U
S\subseteq U
S⊆U,我们有:
∣
S
∣
=
∣
U
∣
−
∣
U
−
S
∣
|S|=|U|-|U-S|
∣S∣=∣U∣−∣U−S∣
根据补集的定义即可得到上式.
对应到计数问题中,当我们计算满足某个条件的方案数时,可以先计算出总共的方案数,再计算出不满足这个条件的方案数,前者减去后者就是原问题的答案.
二.容斥原理.
考虑对于两个集合
A
,
B
A,B
A,B,它们的并的大小和交的大小之间的关系式怎么样的?显然有关系:
∣
A
∪
B
∣
=
∣
A
∣
+
∣
B
∣
−
∣
A
∩
B
∣
|A \cup B|=|A|+|B|-|A\cap B|
∣A∪B∣=∣A∣+∣B∣−∣A∩B∣
那么如果是三个集合
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|
∣A∪B∪C∣=∣A∣+∣B∣+∣C∣−∣A∩B∣−∣A∩C∣−∣B∩C∣+∣A∩B∩C∣
以此类推下去,我们会得到一个
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=1⋃nSi∣∣∣∣∣=T⊆[n]∑(−1)∣T∣−1∣∣∣∣∣i∈T⋂Si∣∣∣∣∣
但是这个关系式是否正确呢?答案是正确的,这个式子被称为容斥原理.
证明:
考虑数学归纳法:
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=1⋃kSi∣∣∣∣∣=∣∣∣∣∣(i=1⋃k−1Si)∪Sk∣∣∣∣∣=∣∣∣∣∣i=1⋃k−1Si∣∣∣∣∣+∣Sk∣−∣∣∣∣∣(i=1⋃k−1Si)∩Sk∣∣∣∣∣=∣∣∣∣∣i=1⋃k−1Si∣∣∣∣∣+∣Sk∣−∣∣∣∣∣i=1⋃k−1(Si∩Sk)∣∣∣∣∣=T⊆[k−1]∑(−1)∣T∣−1∣∣∣∣∣i∈T⋂Si∣∣∣∣∣+∣Sk∣−T⊆[k−1]∑(−1)∣T∣−1∣∣∣∣∣(i∈T⋂Si)∩Sk∣∣∣∣∣=T⊆[k]∑(−1)∣T∣−1∣∣∣∣∣i∈T⋂Si∣∣∣∣∣
证毕.
其实,通过类似的证明方法,我们还可以得到一种容斥原理的变形:
∣
⋂
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=1⋂nSi∣∣∣∣∣=T⊆[n]∑(−1)∣T∣−1∣∣∣∣∣i∈T⋃Si∣∣∣∣∣
三.广义容斥原理.
广义容斥原理:对于两个函数定义域为集合的函数
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)=S2⊆S1∑g(S2)⇔g(S1)=S2⊆S1∑(−1)∣S1∣−∣S2∣f(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)=S2⊆S1∑S3⊆S2∑(−1)∣S2∣−∣S3∣f(S3)=S2⊆S1∑f(S2)S2⊆S3⊆S1∑(−1)∣S3∣−∣S2∣=S2⊆S1∑f(S2)i=0∑∣S1∣−∣S2∣(−1)i(i∣S1∣−∣S2∣)=S2⊆S1∑f(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)=S2⊆S1∑g(S2)f(S1)=S2⊆S1∑(−1)∣S1∣−∣S2∣g(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=1→n,并进行所有与它相关的转移就可以了.
时间复杂度 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∣=∣S2∣⇒f(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=0∑i(ji)g(j)⇔g(i)=j=0∑i(−1)i−j(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=1⋃nSi)=T⊆[n]∑(−1)∣T∣f(i∈T⋂Si)⇔f(i=1⋂nSi)=T⊆[n]∑(−1)∣T∣f(i∈T⋃Si)f(i=1⋃nSi)=T⊆[n]∏f(−1)∣T∣(i∈T⋂Si)⇔f(i=1⋂nSi)=T⊆[n]∏f(−1)∣T∣(i∈T⋃Si)
容易发现这就是广义容斥原理的一个特例,故不再证明.
这两个式子在多重集意义下仍然是成立的.
七.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=1⋂nS(ai))i=1maxn{ai}=max(i=1⋃nS(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=1⋃nS(ai)}=T⊆[n]∑(−1)∣T∣−1max{i=1⋂mS(ai)}=T⊆[n]∑(−1)∣T∣−1i∈Tmin{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)∣T∣−1i∈Tmax{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)∣T∣−1i∈Tmin{ai}⇔i=1minn{ai}=T⊆[n]∑(−1)∣T∣−1i∈Tmax{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)∣T∣−1E(i∈Tmin{ai})⇔E(i=1minn{ai})=T⊆[n]∑(−1)∣T∣−1E(i∈Tmax{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)=∏i∈Si.
显然我们有:
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=1⋂nS(ai))lcmi=1n(ai)=f(i=1⋃nS(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=1⋃nS(ai))=T⊆[n]∏f(−1)∣T∣−1(i=1⋂nS(ai))=T⊆[n]∏gcdi∈T(−1)∣T∣−1(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]∏gcdi∈T(−1)∣T∣−1(ai)⇔gcdi=1n{ai}=T⊆[n]∏lcmi∈T(−1)∣T∣−1(ai)