原论文:《对互异关系的容斥》。
还参考了:《互异关系容斥&集合幂级数小记》。
问题
问题:给定集合 \(S\),求有多少 \(S\) 的大小为 \(n\) 的子集满足元素 \(\oplus\) 和为 \(k\)。
给子集中的元素确定顺序:给定集合 \(S\),求有多少长度为 \(n\)、值域为 \(S\) 的序列 \(a\) 满足 \(\bigoplus_{i=1}^na_i=k\) 且 \(\forall i\neq j,a_i\neq a_j\)。除以 \(n!\) 即得原问题答案。
例题:\(S=\{0,1,\ldots,2^t-1\}\)(记 \(m=|S|=2^t\)),\(\oplus\) 表示异或,\(k=0\)。
对边集容斥
对 \(\forall i\neq j,a_i\neq a_j\) 容斥。令无向边 \((i,j)\) 表示 \(a_i=a_j\),则我们要对 \(n\) 阶完全图 \(K_n\) 的边集 \(E_n\) 的子集进行容斥。钦定边集 \(E\) 的限制全被满足,则要求 \(\emptyset\) 的限制恰好被满足。于是子集反演得到 \(E\) 的容斥系数为 \((-1)^{|E|}\)。设其方案数为 \(V(E,k)\),则答案为:
\[ans_k=\sum_{E\subseteq E_n}(-1)^{|E|}V(E,k)
\]
推导
设 \(C(E)\) 表示 \(E\) 在 \(n\) 个点中形成的连通块的集合,\(|c|\) 表示一个连通块的点数。则:
\[V(E,k)=
\begin{cases}
m^{|C(E)|} & k=0,\forall c\in C(E),2\mid|c| \\
0 & k>0,\forall c\in C(E),2\mid|c| \\
m^{|C(E)|-1} & \exists c\in C(E),2\not\mid|c|
\end{cases}
\]
第三条是因为在 \(S\) 中逆元存在且唯一,故选一个等价类出来,随意填剩下的 \(|C(E)|-1\) 个等价类,将这个等价类的值赋为逆元即可。
于是显然有(注意下降幂):
\[\begin{gathered}
ans_1=ans_2=\ldots=ans_{m-1} \\
\sum_{i=0}^{m-1}ans_i=m^\underline n
\end{gathered}
\]
我们求出 \(ans_0-ans_1\),则:
\[\begin{gathered}
ans_0={(m-1)(ans_0-ans_1)+\sum_{i=0}^{m-1}ans_i\over m} \\
ans_i={-ans_0+\sum_{i=0}^{m-1}ans_i\over m-1} \ (i\geq1)
\end{gathered}
\]
对点集算贡献
接下来计算 \(ans_0-ans_1\),设为 \(f_n\)。这一步将对边集的容斥变成对点集算贡献,若只关心点集大小则使用归纳 / EGF,否则使用集合幂级数。
\[f_n=\sum_{E\subseteq E_n,\forall c\in C(E),2\mid|c|}(-1)^{|E|}m^{|C(E)|}
\]
这一步可以像原论文那样 DP,也可以来一点 GF:
由于不同连通块点集的导出子图的边集独立,且连通块间不连边,我们可以在连通块内枚举边集。那么大小为 \(n\) 的连通块的贡献 \(g_n\) 为:
\[g_n=m\sum_{E\subseteq E_n,连通}(-1)^{|E|}
\]
直接上 \(\ln\)(EGF)来搞连通性:
\[\begin{gathered}
h_n=\sum_{E\subseteq E_n}(-1)^{|E|}=[n=1] \ (n\geq1) \\
\hat H(x)=1+\sum_{n\geq1}h_n{x^n\over n!}=1+x \\
\hat G(x)=m\ln\hat H(x)=m\ln(1+x)=m\sum_{n\geq1}{(-1)^{n-1}\over n}x^n \\
g_n=[{x^n\over n!}]\hat G(x)=m(-1)^{n-1}(n-1)! \ (n\geq1)
\end{gathered}
\]
再用单位根反演求大小为偶数的连通块的 EGF(由于这里仅仅是 \(2\mid n\),动用人类智慧也可以想出):
\[\hat P(x)={\hat G(x)+\hat G(-x)\over2}={m\over2}(\ln(1+x)+\ln(1-x))
\]
最后求一发 \(\exp\) 再提取系数即可得到 \(f_n\):
\[\begin{gathered}
\hat F(x)=\exp\hat P(x)=(1-x^2)^{m\over2} \\
(n\geq1) \ f_n=[{x^n\over n!}]\hat F(x)=
\begin{cases}
(-1)^{m/2}{m/2\choose n/2}n! & 2\mid n \\
0 & 2\not\mid n
\end{cases}
\end{gathered}
\]
带回去求得 \(ans_0\),除以 \(n!\) 即为最开始的问题的答案:
\(2\mid n\) :
\[{ans_0\over n!}={(m-1)(-1)^{m/2}{m/2\choose n/2}n!+m^\underline n\over m\cdot n!}={(m-1)(-1)^{m/2}{m/2\choose n/2}+{m\choose n}\over m}
\]
\(2\not\mid n\) :
\[{ans_0\over n!}={m^\underline n\over m\cdot n!}={{m\choose n}\over m}
\]
总结
-
将等价关系看作无向图的连边,将等价类看作连通块,对边集进行容斥。
-
扩展到所有 \(k\),表示 \(V(E,k)\)。利用方案数相同、已知总和的性质,只需计算 \(a_0-a_1\),简化对容斥贡献的讨论。
- 通常保证 \(\oplus\) 在 \(S\) 中的逆元存在且唯一(例如异或、取模加),这样可以选一个等价类来作为逆元。
-
计算 \(a_0-a_1\):对点集计算贡献。
另:子集与不重复的序列可以互相转化。
2025.8.19