【笔记】容斥原理

我很菜,没写完,没写完,,,

只会抄讲义,好垃圾

集合的并集

容斥原理,说到这个算法你最先想到什么?

求解一些集合并集的大小?

我们从结论出发,说明一下容斥原理的原理:假设我们要求 \(|A\cup B\cup C\cup D|\)

\[\begin{aligned} |A\cup B\cup C\cup D|&=|A|+|B|+|C|+|D|\\ &-|A\cap B|-|A\cap C|-|A\cap D|-|B\cap C|-|B\cap D|-|C\cap D|\\ &+|A\cap B\cap C|+|A\cap C\cap D|+|A\cap B\cap D|+|A\cap B\cap C|\\ &+|A\cap B\cap C\cap D|. \end{aligned}\]

好的我们证一下它的正确性:以一个元素 \(f\not\in A,f\in B,f\in C,f\in D\) 举例,在第一行算了 \(\binom{3}{1}\) 次,第二行减掉 \(\binom{3}{2}\) 次,第三行加上 \(\binom{3}{3}\) 次。

从组合数学的角度,一个方案如果恰好属于 \(k\) 个集合那么它会被算:

\[\begin{aligned} &\sum_{1\leq i\leq k}(-1)^{i+1}\binom{k}{i}\\ =&-\sum_{1\leq i\leq k}(-1)^i\binom{k}{i}\\ =&-\left(\sum_{0\leq i\leq k}(-1)^i\binom{k}{i}-1\right)\\ =&-(1-1)^k+1\quad\text{(a=-1,b=1 的二项式定理)}\\ =&1-0^k. \end{aligned}\]

这意味着如果 \(k=0\) 即完全不在任何一个集合的元素会被算 \(0\) 次,而在并集里的元素会被算 \(1\) 次,

我们归纳一下:

\[\begin{aligned} |S_1\cup S_2\cup\cdots\cup S_n|=\sum_{T\subseteq\{1,2,\cdots,n\}}(-1)^{|T|+1}|S_{T_1}\cap S_{T_2}\cap\cdots\cap S_{T_{|T|}}|. \end{aligned}\]

你已经接触了容斥原理!

二项式反演

祈祷一下写的都没错

形式一:子集枚举

首先摆一下结论:

\[g(S)=\sum_{S\subseteq T}f(T)\Leftrightarrow f(T)=\sum_{T\subseteq S}g(S)\cdot(-1)^{|S|-|T|}. \]

\[g(S)=\sum_{T\subseteq S}f(T)\Leftrightarrow f(T)=\sum_{S\subseteq T}g(S)\cdot(-1)^{|T|-|S|}. \]

好的我们把它抛到一边我们考虑这样一个问题:我有 \(n\) 个限制条件,我可以很快的求出 \(g(S)\) 表示满足 \(S\) 中所有限制条件其它随意的方案数,怎么求出:

  1. 恰好满足 \(S\) 中的限制条件,其它的不满足?\(f(T)=\sum_{T\subseteq S}g(S)\cdot(-1)^{|S|-|T|}.\)
  2. 恰好不满足任何限制条件:\(f(\varnothing)=\sum_S g(S)\cdot(-1)^{|S|}.\)
  3. 至少满足一样限制条件:首先明确 \(g(\varnothing)\) 就是所有方案数,那么 \(ans=g(\varnothing)-f(\varnothing)=\sum_{S\neq\varnothing} g(S)\cdot(-1)^{|S|-1}.\)
  4. 恰好满足 \(k\) 样限制条件:……?

\[\begin{aligned} \sum_{|S|=k}f(S)&=\sum_{|S|=k}\sum_{S\subseteq T}g(T)\cdot(-1)^{|T|-|S|}\\ &=\sum_{|S|\geq k}g(S)\sum_{T\subseteq S,|T|=k}(-1)^{|S|-|T|}\\ &=\sum_{|S|\geq k}g(S)\cdot\boxed{\binom{|S|}{k}\cdot(-1)^{|S|-k}}\\ &=\sum_{s\geq k}\binom{s}{k}\cdot(-1)^{s-k}\sum_{|S|=s}g(S). \end{aligned}\]

组合意义解释一下这个容斥系数:\((-1)^{|S|-k}\) 是容斥,\(\binom{|S|}{k}\) 是说这一项的所有大小为 \(k\) 的子集都有影响,都要容斥一遍。

  1. 那么至少满足 \(k\) 样限制条件呢?

\[\begin{aligned} \sum_{|S|\geq k}f(S)&=\sum_{i\geq k}\sum_{|S|\geq i}g(S)\cdot\binom{|S|}{i}\cdot(-1)^{|S|-i}\\ &=\sum_{|S|\geq k}g(S)\sum_{|S|\geq i\geq k}\binom{|S|}{i}\cdot(-1)^{|S|-i}\\ &=\sum_{|S|\geq k}g(S)A(|S|,k)\\ \end{aligned}\]

其中我们强令了 \(A(n,k)=\sum_{k\leq i\leq n}\boxed{\binom{n}{i}\cdot(-1)^{n-i}}.\) 天啊好像

于是我们得到了一个阳间的算法。

形式二

\[g(k)=\sum_{k\leq i\leq n}\binom{i}{k}f(i)\Leftrightarrow f(k)=\sum_{k\leq i\leq n}(-1)^{i-k}\binom{i}{k}g(i). \]

\[g(k)=\sum_{m\leq i\leq k}\binom{k}{i}f(i)\Leftrightarrow f(k)=\sum_{m\leq i\leq k}(-1)^{k-i}\binom{k}{i}g(i). \]

右边是形式一问题四,左边是怎么来的呢?我们重申一次 \(f,g\) 的组合意义:\(f(t)\) 是所有的恰好满足 \(t\) 个条件的方案数,\(g(t)\)钦定了任意 \(t\) 个条件后的方案数的和,对于每一个方案他会重复数 \(\binom{|S|}{t}\) 次!

题一

LGP5188 [COCI2009-2010#4] PALACINKE

由于难点在 DP,这里 skip

题二

problem

两个 \(n\leq 2000\) 的数组 \(A,B\),元素互不相同,求有多少种将 \(A,B\) 配对的方法使得 \(A>B\) 的恰好有 \(k\) 对。

题目改过,但是这一步转换很简单。

solution

恰好很难算。我们算至少:\(g(t)\) 表示钦定 \(t\) 个 pair 是大于有多少种方案,\(f(t)\) 表示恰好有 \(t\) 个 pair 是大于有多少种方案。

二项式反演:

\[g(k)=\sum_{k\leq i\leq n}\binom{i}{k}f(i)\Leftrightarrow f(k)=\sum_{k\leq i\leq n}(-1)^{i-k}\binom{i}{k}g(i). \]

但是这个题的难点不在这里,我们要算 \(g\),怎么算呢?DP。

首先 \(A,B\) 排序对结果无影响,然后二分求出 \(h_i=\sum_j[b_j<a_i]\) 表示有多少个 \(b\) 小于 \(a\)

\(f_{i,j}\) 表示考虑到 \(a_i\),前面有 \(j\) 个已经匹配。

  • \(i\) 不匹配:\(f_{i-1,j}\)
  • \(i\) 匹配:\((h_i-j+1)f_{i-1,j-1}\),这表示 \(i\) 的匹配对象中,\(j-1\) 个已经被用了,其他的随便挑一个。

然后剩下的随机匹配,得到 \(g(t)=f_{n,j}(n-j)!\)

题三

我们复习一下:\(\mu*I=e\),也就是 \([n=1]=\sum_{d|n}\mu(d)\)。这个 \(\mu(d)\) 我们也可以看作是一种容斥系数。

这里用一道习题讲解它的应用形式:题解 ABC230G【GCD Permutation】

problem

给你一个长度为 \(N\) 的排列 \(P=(P_1,P_2,...,P_N)\),你需要求出有多少 \((i,j)\) 满足 \(1\leq i \leq j \leq N,\gcd(i,j)\ne 1,\gcd(P_i,P_j)\ne 1\)

\(n\leq 200000\)

以下忽略 \(i=j\) 的 pair。

solution 0

考虑一个简化的问题:你有一些不重复的数,求有多少个有序的 pair 使得 \(\gcd(p_i,p_j)=1\)。这是简单的,使用祖传莫比乌斯反演:\(\mu*I=e\)

\[\begin{aligned} &\sum_{1\leq i\leq n}\sum_{1\leq j\leq n}[\gcd(p_i,p_j)=1]\\ &=\sum_{1\leq i\leq n}\sum_{1\leq j\leq n}\sum_{d|\gcd(p_i,p_j)}\mu(d)\\ &=\sum_{1\leq i\leq n}\sum_{1\leq j\leq n}\sum_{d|\gcd(p_i,p_j)}\mu(d)\\ &=\sum_{1\leq i\leq n}\sum_{1\leq j\leq n}\sum_{d|p_i,d|p_j}\mu(d)\\ &=\sum_d\mu(d)(\sum_{i}[d|p_i])^2=\sum_d\mu(d)cnt_d^2. \end{aligned}\]

请注意这里 \(cnt_d\) 表示 有多少个 \(d\) 的倍数在数列里。

那么我们有一个算法:对于每一个数,枚举这个数的所有因数,统计 \(cnt_d\),统计上式。

如果我们忽略所有的 \(\mu(d)=0\) 的点,它的复杂度是 \(\sum_{1\leq i\leq n}2^{\omega(i)}<O(n^{1.5})\)。好吧这是个无效放缩。。。。

solution 1

我们进化出一个数据结构,支持插入删除,查询集合中有多少个不互质的 pair。

简单的。

solution 2

我们算出所有满足 \(\gcd(i,j)=1\land\gcd(p_i,p_j)\neq1\) 的 pair,用所有 \(\gcd(p_i,p_j)\neq1\) 的 pair 数一减,就是答案了。

我们的方法是:枚举 \(d\),然后拎出所有的下标为 \(d\) 的倍数的 \(p_i\),计算这里面有多少个不互质的 pair。我们假装,它的贡献是 \(\mu(d)\)

于是这样计算就对了。这本质上是容斥套容斥。

对数据结构更新的次数显然为 \(O(n\ln n)\),那么总的复杂度是 \(O(n^{1.5}\ln n)\)。完全跑不满。

题四

problem

求出 \(h(n,m,k)\):将 \(n\) 个相同的小球放入 \(m\) 个互不相同的盒子里,要求每个盒子最少 \(0\) 个最多 \(k\) 个的方案数。

solution

  • 辅助 \(g(n,m)\):将 \(n\) 个相同的小球放入 \(m\) 个互不相同的盒子里,要求每个盒子最少 \(0\)最多 \(k\)的方案数,明显 \(g(n,m)=\binom{n+m-1}{m-1}\)
  • 容斥。考虑钦定 \(i\) 个盒子溢出了,将这些盒子的球数减去 \((k+1)\)。现在数一下:\(\Delta=i(k+1),ans=g(n-\Delta,m)\)
  • 盲猜容斥系数为 \((-1)^i\binom{m}{i}\),所以 \(h(n,m,k)=\sum_{0\leq i\leq m} (-1)^i\binom{m}{i}g(n-\Delta,m)\)

(关于这一步什么鬼,如果你无法理解可以看看 完整题解

扩展:\(H(n,m,[L,R])\) 表示将 \(n\) 个相同的小球放入 \(m\) 个互不相同的盒子里,要求每个盒子最少 \(L\) 个最多 \(R\) 个的方案数,很不幸它是 \(h(n-mL,m,R-L)\)

题五

problem

一个有向图有 \(n\) 个点,求它的 DAG 子图数量。\(n\leq 15\)

solution

\(f[S]\) 表示点集 \(S\) 有多少个 DAG 子图。枚举这个 DAG 中入度为 0 的部分,然后递归下去。

\[f[S]=\sum_{T\subseteq S,T\neq\varnothing}2^{ways(T,S-T)}f[S-T]. \]

由于不能一次枚举完所有入度为 0 的点,同一种方案会算重,我们对着这些点容斥。

\[f[S]=\sum_{T\subseteq S,T\neq\varnothing}(-1)^{|T|+1}2^{ways(T,S-T)}f[S-T]. \]

题六

BZOJ3812 [清华集训 2014] 主旋律

problem

给定一个 \(n\) 个点的有向图,问这个图有多少个强连通子图。保证 \(n\leq 15\)

solution

一个非强连通的子图,缩点后是一个至少两个点的 DAG(这个 DAG 可以不连通)。

对于点集 \(S\),考虑强连通子图 = 所有图 - 非强连通子图。

令强连通子图的数量为 \(f[S]\),枚举 \(T\subset S\),使 \(T\) 是一个强连通分量,\(S-T\) 就随意,而且强制规定 \(T\) 在缩点图的入度为零。

\[f[S]=all[S]-\sum_{T\subset S}2^{ways(T,S-T)}f[T]all[S-T]. \]

  • \(all[S]\) 表示所有图的数量。
  • \(ways(S,T)\) 表示 \(\sum_{u\in S,v\in T}g[u][v]\)。注意到 \(S\cap T=\varnothing\),它的复杂度顶满是 \(O(3^nn^2)\)

错误的。考虑 \(1\to 3,2\to 3\) 会被算两次。

考虑问题在哪里呢?枚举 \(T\) 的时候,我们没有钦定 \(T\) 一定是所有的入度为 \(0\) 的点。我们对着 \(T\) 容斥:

  • \(T\) 划分为若干个强连通分量,奇数个的贡献是 1,偶数个的贡献是 -1;
  • \(g[T]\) 表示所有划分方案的和。

\(f[T]\) 换成 \(g[T]\) 就行了。

\[f[S]=all[S]-\sum_{T\subset S}2^{ways(T,S-T)}g[T]all[S-T]. \]

怎么算 \(g[S]\)

  • 枚举一个 \(T\subset S\),然后划分成 \(-f[T]g[S-T]\)
  • 细节一:一种好的做法是令 \(g[0]=0\),然后特判 \(T\) 是整一块强连通分量的情况。
  • 细节二:为了避免判重等奇奇怪怪的问题,我们钦定一个 \(x\in S\),然后枚举 \(x\in T\land T\subset S\)

\[g[S]=f[S]-\sum_{x\in T\subset S}f[T]g[S-T]. \]

todo

  • BZOJ4455 [ZJOI2016] 小星星
  • BZOJ4596 [SHOI2016] 黑暗前的幻想乡

BZOJ 4350 括号序列再战猪猪侠

BZOJ 1566 管道取珠

51nod 1327 棋盘游戏

HDU 6416 Rikka with Seam

BZOJ 2169 连边

有点难写的计数题

Project Euler 452 Lattice Quadrilaterals

51nod 1303 交叉矩阵

posted @ 2023-01-05 22:38  caijianhong  阅读(89)  评论(0编辑  收藏  举报