【笔记】容斥原理

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

只会抄讲义,好垃圾

集合的并集

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

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

我们从结论出发,说明一下容斥原理的原理:假设我们要求 |ABCD|

|ABCD|=|A|+|B|+|C|+|D||AB||AC||AD||BC||BD||CD|+|ABC|+|ACD|+|ABD|+|ABC|+|ABCD|.

好的我们证一下它的正确性:以一个元素 fA,fB,fC,fD 举例,在第一行算了 (31) 次,第二行减掉 (32) 次,第三行加上 (33) 次。

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

1ik(1)i+1(ki)=1ik(1)i(ki)=(0ik(1)i(ki)1)=(11)k+1(a=-1,b=1 的二项式定理)=10k.

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

我们归纳一下:

|S1S2Sn|=T{1,2,,n}(1)|T|+1|ST1ST2ST|T||.

你已经接触了容斥原理!

二项式反演

祈祷一下写的都没错

形式一:子集枚举

首先摆一下结论:

g(S)=STf(T)f(T)=TSg(S)(1)|S||T|.

g(S)=TSf(T)f(T)=STg(S)(1)|T||S|.

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

  1. 恰好满足 S 中的限制条件,其它的不满足?f(T)=TSg(S)(1)|S||T|.
  2. 恰好不满足任何限制条件:f()=Sg(S)(1)|S|.
  3. 至少满足一样限制条件:首先明确 g() 就是所有方案数,那么 ans=g()f()=Sg(S)(1)|S|1.
  4. 恰好满足 k 样限制条件:……?

|S|=kf(S)=|S|=kSTg(T)(1)|T||S|=|S|kg(S)TS,|T|=k(1)|S||T|=|S|kg(S)(|S|k)(1)|S|k=sk(sk)(1)sk|S|=sg(S).

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

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

|S|kf(S)=ik|S|ig(S)(|S|i)(1)|S|i=|S|kg(S)|S|ik(|S|i)(1)|S|i=|S|kg(S)A(|S|,k)

其中我们强令了 A(n,k)=kin(ni)(1)ni. 天啊好像

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

形式二

g(k)=kin(ik)f(i)f(k)=kin(1)ik(ik)g(i).

g(k)=mik(ki)f(i)f(k)=mik(1)ki(ki)g(i).

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

题一

LGP5188 [COCI2009-2010#4] PALACINKE

由于难点在 DP,这里 skip

题二

problem

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

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

solution

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

二项式反演:

g(k)=kin(ik)f(i)f(k)=kin(1)ik(ik)g(i).

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

首先 A,B 排序对结果无影响,然后二分求出 hi=j[bj<ai] 表示有多少个 b 小于 a

fi,j 表示考虑到 ai,前面有 j 个已经匹配。

  • i 不匹配:fi1,j
  • i 匹配:(hij+1)fi1,j1,这表示 i 的匹配对象中,j1 个已经被用了,其他的随便挑一个。

然后剩下的随机匹配,得到 g(t)=fn,j(nj)!

题三

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

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

problem

给你一个长度为 N 的排列 P=(P1,P2,...,PN),你需要求出有多少 (i,j) 满足 1ijN,gcd(i,j)1,gcd(Pi,Pj)1

n200000

以下忽略 i=j 的 pair。

solution 0

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

1in1jn[gcd(pi,pj)=1]=1in1jnd|gcd(pi,pj)μ(d)=1in1jnd|gcd(pi,pj)μ(d)=1in1jnd|pi,d|pjμ(d)=dμ(d)(i[d|pi])2=dμ(d)cntd2.

请注意这里 cntd 表示 有多少个 d 的倍数在数列里。

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

如果我们忽略所有的 μ(d)=0 的点,它的复杂度是 1in2ω(i)<O(n1.5)。好吧这是个无效放缩。。。。

solution 1

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

简单的。

solution 2

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

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

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

对数据结构更新的次数显然为 O(nlnn),那么总的复杂度是 O(n1.5lnn)。完全跑不满。

题四

problem

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

solution

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

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

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

题五

problem

一个有向图有 n 个点,求它的 DAG 子图数量。n15

solution

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

f[S]=TS,T2ways(T,ST)f[ST].

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

f[S]=TS,T(1)|T|+12ways(T,ST)f[ST].

题六

BZOJ3812 [清华集训 2014] 主旋律

problem

给定一个 n 个点的有向图,问这个图有多少个强连通子图。保证 n15

solution

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

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

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

f[S]=all[S]TS2ways(T,ST)f[T]all[ST].

  • all[S] 表示所有图的数量。
  • ways(S,T) 表示 uS,vTg[u][v]。注意到 ST=,它的复杂度顶满是 O(3nn2)

错误的。考虑 13,23 会被算两次。

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

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

f[T] 换成 g[T] 就行了。

f[S]=all[S]TS2ways(T,ST)g[T]all[ST].

怎么算 g[S]

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

g[S]=f[S]xTSf[T]g[ST].

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 @   caijianhong  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示