浅谈二项式反演与容斥
广告
你还在为计数题发愁吗?
你还在为算重算漏担忧吗?
来试试容斥二项式反演吧!
简介
(上面写的是啥)
二项式反演的用途很多,其中一个比较大的用途是在计数问题中进行容斥
或者说「二项式反演的本质就是容斥」
它可以将「符合某种条件的有至少k个」或者「符合某种条件的有恰好k个」转化为「钦定符合某种条件的有k个」的问题(厉害吧)
算法
还是得先把式子拿出来
只需用到一种形式:
好吧别管这个,还是拿一个题目为例
题目
题意:一个长度为 \(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_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\) 次
Ohhhhhhhhh
等下,我们要求的不是 \(G\) 嘛,这个和式算的咋是 \(F\) ?
接下来隆重请出今天的主角——「二项式反演」!
(背下来~~)
啊这,好像还是 \(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)\) ),有的问题中二项式反演好用(比如这题)
这样就理解透了吧~
题目
-
[TJOI2019]唱、跳、rap和篮球
容斥
-
CF1228E Another Filling the Grid
-
CF997C Sky Full of Stars
二维容斥
-
P5400 [CTS2019]随机立方体
二项式反演(计数部分有点难)
-
P6478 [NOI Online #2 提高组]游戏
二项式反演(套了层外衣)