浅谈二项式反演与容斥

广告

你还在为计数题发愁吗?

你还在为算重算漏担忧吗?

来试试容斥二项式反演吧!


简介

(上面写的是啥)

二项式反演的用途很多,其中一个比较大的用途是在计数问题中进行容斥

或者说「二项式反演的本质就是容斥

它可以将「符合某种条件的有至少k个」或者「符合某种条件的有恰好k个」转化为「钦定符合某种条件的有k个」的问题(厉害吧)

算法

还是得先把式子拿出来

只需用到一种形式:

\[F(k)=\sum\limits_{i=k}^t C_i^k G(i) \iff G(k)=\sum\limits_{i=k}^t (-1)^{i-k} C_i^k F(i) \]

好吧别管这个,还是拿一个题目为例

题目

P4491 [HAOI2018]染色

题意:一个长度为 \(n\) 的序列, 每个位置都可以被染成 \(m\) 种颜色中的某一种,对于每一种序列计算其中恰好出现了 \(s\) 次的颜色的种数。

问题1:求钦定至少有 \(k\) 种的序列数量。

问题2:求至少有 \(1\) 种的序列数量 \(S(1)\)

问题3:求至少/恰好有 \(k\) 种的序列数量 \(S(k)/G(k)\)

显然符合要求的颜色种数不超过 \(\min\{m,\frac{n}{s}\}\),为了方便把它记为 \(t\)

\(t \leq 10^5\)

从钦定入手

问题1:求钦定至少有 \(k\) 种的序列数量。

先从 \(m\) 种颜色中选出 \(k\) 个,\(C_m^k\)

再从 \(n\) 个位置中选出 \(sk\) 个放进去,\(C_n^{sk}\)

\(k\) 种颜色放进去,即可重排列,\(\dfrac{(sk)!}{(s!)^k}\)

剩下的位置乱放,但只能放别的颜色了(不然就不是恰好出现 \(s\) 次了),\((m-k)^{n-sk}\)

\[C_m^kC_n^{sk}\dfrac{(sk)!}{(s!)^k}(m-k)^{n-sk} \]

如果你把 \(C_n^{sk}\) 拆开的话?

\[C_m^k\dfrac{n!}{(n-sk)!(s!)^k}(m-k)^{n-sk} \]

轻松解决~

为了好记把这东西记成 \(F(k)\)

有同学要说了,这不就是问题 3 的答案吗

显然不是……

虽然没有算漏,但它算重了

原因就在于随便填的那部分可能也有恰好出现 \(s\) 次的颜色

这没什么问题,可是 \(F(k)\) 把它算了不止一次

比如 1 2 3 4(这是颜色),在 1 2 3 里算了一次,在 1 2 4 里又算了一次,在 2 3 4 里又算了一次

显然算重的次数就是组合数,也就是说,\(k'\) 会被 \(k\) 计算 \(C_{k'}^k\)

从容斥说起

问题2:求至少有 \(1\) 种的序列数量。

来考虑一个容斥

首先加入 \(F(1)\) ,很遗憾的是,算重了一堆

我们来考虑 \(k=2\) ,它被 \(F(1)\) 算了 \(2\) 次,就减掉 \(1\)\(F(2)\)

我们来考虑 \(k=3\) ,它被 \(F(1)\) 算了 \(3\) 次,被 \(F(2)\) 算了 \(3\) 次,算没了,那就加上 \(1\)\(F(3)\)

我们来考虑 \(k=4\) ,它被 \(F(1)\) 算了 \(4\) 次,被 \(F(2)\) 算了 \(6\) 次,被 \(F(3)\) 算了 \(4\) 次,那就减去 \(1\)\(F(4)\)

……

啊,这不就是容斥吗

所以 \(S(1)=\sum\limits_{i=1}^t (-1)^{i-1}F(i)\)

(至于为什么就一定是 \((-1)^{i-1}\) 呢,别着急,马上会解释)


问题3:求至少/恰好有 \(k\) 种的序列数量。

参照刚才的容斥,是差不多的

首先加入 \(F(k)\) ,很遗憾的是,还是算重了一堆

我们来考虑 \(k+1\) ,它被 \(F(k)\) 算了 \(C_{k+1}^1\) 次,就减掉 \(C_{k+1}^1-1\)\(F(k+1)\)

我们来考虑 \(k+2\) ,它被 \(F(k)\) 算了 \(C_{k+2}^2\) 次,被 \(F(k+1)\) 算了 \(C_{k+2}^1\) 次,已经算了 \(C_{k+2}^2-C_{k+2}^1 (C_{k+1}^1-1)=C_{k+2}^1-C_{k+2}^2\) 次,就加上 \(1-C_{k+2}^1+C_{k+2}^2\)\(F(k+2)\)

规律出现

所以 \(S(k)=\sum\limits_{i=k}^t F(i)\sum\limits_{j=k}^i (-1)^{i-j} C_i^j\)


那么刚刚那个 \(k=1\) 的情况怎么解释呢?

把第二个和号拎出来,然后把 \(k=1\) 代进去

\(\sum\limits_{j=1}^i (-1)^{i-j} C_i^j = (-1)^{i}\sum\limits_{j=1}^i (-1)^j C_i^j\)

这不就是「二项式定理」嘛?

\(\sum\limits_{j=1}^i (-1)^j C_i^j=\sum\limits_{j=0}^i (-1)^j C_i^j-1=(1-1)^i-1=-1\)

所以 \(S(1)=\sum\limits_{i=1}^t (-1)^{i}F(i)\sum\limits_{j=1}^i (-1)^j C_i^j = \sum\limits_{i=1}^t (-1)^{i-1}F(i)\)

妙啊

二项式反演

好,现在忘掉刚刚的东西

刚刚的东西显然可以 \(O(t^2)\) 计算了,但是也显然不太行

让我们换一个思路

这回不容斥了,直接从算重这个问题入手

\(G(k)\) 为出现 \(s\) 次的颜色恰好\(k\) 种的序列数量

考虑 \(F(k)\) 都算了些啥

对于 \(G(k')\) 来说,\(F(k)\) 算了 \(C_{k'}^k\)

\[F(k)=\sum\limits_{i=k}^t G(i)C_i^k \]

Ohhhhhhhhh

等下,我们要求的不是 \(G\) 嘛,这个和式算的咋是 \(F\)

接下来隆重请出今天的主角——「二项式反演」!

\[F(k)=\sum\limits_{i=k}^t C_i^k G(i) \iff G(k)=\sum\limits_{i=k}^t (-1)^{i-k} C_i^k F(i) \]

来~~


啊这,好像还是 \(O(t^2)\)

试着拆式子

\(G(k)=\sum\limits_{i=k}^t (-1)^{i-k} \dfrac{i!}{k!(i-k)!} F(i)\)

咦,有点卷积的意思了

\(G(k) \cdot k!=\sum\limits_{i=k}^t \dfrac{(-1)^{i-k}}{(i-k)!} F(i) \cdot i!\)

好吧就是个差卷积

于是我们成功的做到了 \(O(tlogt)\)

二项式反演与容斥

是不是有点莫名其妙?

我们来把两个部分得到的东西比较一下

容斥:

\(S(k)=\sum\limits_{i=k}^t F(i)\sum\limits_{j=k}^i (-1)^{i-j} C_i^j\)

二项式反演:

\(S(k)=\sum\limits_{i=k}^t G(i)=\sum\limits_{i=k}^t \sum\limits_{j=i}^t (-1)^{j-i} C_j^i F(j)=\sum\limits_{j=k}^t F(j) \sum\limits_{i=k}^j (-1)^{j-i} C_j^i\)

好家伙完全一样

也就是说,其实拿容斥也可以得到这个结果

二项式反演的本质就是容斥

所以这并不是新奇的东西,只是换了个角度看问题而已,也就是说是两种的方法

但是有的问题中容斥好用(比如求 \(S(1)\) ),有的问题中二项式反演好用(比如这题)

这样就理解透了吧~

题目


参考资料

posted @ 2020-12-26 12:58  苹果蓝17  阅读(291)  评论(0编辑  收藏  举报