组合意义天地灭,代数推导保平安。
# 阅读前须知
本博客包含了一些提高到省选难度的组合数学知识点,主要由知识点和笔者做题时遇到的一些题组成。
对于知识点,阅读前需要你掌握最基础的一些组合数学知识,如排列数组合数,插板法等等,还需要一定的推式子能力,其中还会涉及到一部分与多项式和生成函数有关的内容,读者可以自行选择阅读。同时由于笔者能力有限,更高级的多项式和生成函数知识无法涉及到,若想学习可以从网上搜集学习。
题目上笔者也对题目进行了简单分类,读者完全可以只看自己学了的知识点所对应的题目。由于笔者水平有限,题目难度可能不高,还请大家谅解。
同时这篇博客也会在笔者学过更高深的内容后,进行知识上和题目上的不定期的更新。
# 组合数学知识点
# Lucas 定理
当 p 为质数时,有 (mn)≡(m/pn/p)×(mmodpnmodp)(modp)
# 基础组合数公式
定义式: (mn)=m!×(n−m)!n!
二项式定理: (a+b)n=∑i=0n(in)an−ibi
(mn)=(n−mn) ,取补集即可
(kn)=kn(k−1n−1) ,根据定义式直接展开即可
(mn)=(mn−1)+(m−1n−1) ,常见递推式,分别考虑选不选第 m 个得到
∑i=0n(in)=2n ,二项式定理取 a=b=1 时的特殊情况,也可以理解为任意选择
∑i=0n(i−mn−m)=2n−m ,上式变形。
∑i=0n(in)(−1)i=∑i=0n(in)(−1)n−i=[n=0] ,二项式定理取 a=1,b=−1 的特殊情况,只有当 n=0 时答案为 1 。
∑i=0n(in)(m−im)=(mn+m) (n≥m)
∑i=0n(in)2=(n2n) ,上一条取 n=m 的特殊情况
∑i=0ni(in)=n×2n−1
考虑对于 F(x)=(1+x)n=∑i=0n(in)xi ,两边同时求导得 n(1+x)n−1=∑i=1n(in)ixi−1 ,取 x=1 时可得
∑i=0n(mi)=(m+1n+1) ,上指标求和公式,不断递推即可得到
∑i=0n(mm+i)=(mm+n+1) ,平行求和公式,与上指标求和证明类似
(mn)(km)=(kn)(m−kn−k) ,定义式直接化简可得
范德蒙德卷积: ∑i=0k(ir)(k−is)=(kr+s) ,证明如下:
(1+x)r+s=i=0∑r+s(ir+s)xi=(1+x)r×(1+x)s=(i=0∑r(ir)xi)(j=0∑s(js)xj)=i=0∑r+sj=0∑i(jr)(i−js)xi
由于对应项系数相等,所以 ∑i=0k(ir)(k−is)=(kr+s) ,得证。
# 二项式反演
# 常用形式一
设 fn 表示恰好 n 个元素形成特定结构的方案数,gn 表示从 n 个元素中选出 i≥0 个元素形成特定结构的方案数,根据定义我们得到 gn=∑i=0n(in)fi 。若我们已知 gn ,要求解 fi ,有反演公式 fn=∑i=0n(in)(−1)n−igi 。代数推导证明如下(大式子警告!)
fn=i=0∑n(in)(−1)n−igi=i=0∑n(in)(−1)n−ij=0∑i(ji)fj=i=0∑nj=0∑i(in)(ji)(−1)n−ifj=j=0∑nfji=j∑n(in)(ji)(−1)n−i=j=0∑nfji=j∑n(jn)(i−jn−i)(−1)n−i
我们设 k=i−j ,则
fn=j=0∑nfj(jn)k=0∑n−j(kn−j−k)(−1)n−j−k=j=0∑nfj(jn)[n−j=0]=j=0∑nfj(jn)[n=j]=fn
证毕。
其实也有更简单的证法,我们利用 EGF 。
fnn!fnF(x)G(x)gn=i=0∑n(in)gi=i=0∑n(n−i)!1i!gi=exG(x)=F(x)e−x=i=0∑n(in)(−1)n−ifi
我们考虑其实际意义,gn 表示至多 n 个的方案数,fn 表示恰好 n 个的方案数。
gn=∑i=0n(in)fi fn=∑i=0n(−1)n−i(in)gi
# 常用形式二
gk 表示至少 k 个的方案数,fk 表示恰好 k 个的方案数。
gk=∑i=kn(ki)fi fk=∑i=kn(−1)i−k(ki)gi (证明与形式一类似,此处省略)
# 多重集排列数
共有 n 个球,有 k 种,每种球有 ai 个,则所有球的全排列数为 ∏i=1kai!n! 。
# 卡特兰数
卡特兰数常见求解式子,默认 C0=C1=1 。
Cn=n+1(n2n)Cn=i=1∑nCi−1Cn−iCn=Cn−1n+14n−2Cn=(n2n)−(n−12n)
进栈序列为 1 到 n ,求出栈序列数
n 个节点的二叉树数量
长度为 2n 个括号序列数
凸 n+2 边形三角剖分数
以上答案均为卡特兰数第 n 项 Cn 。
# 斯特林数
# 第二类斯特林数
第二类斯特林数,又叫做斯特林子集数。{mn} 表示将 n 个元素划分为 m 个互不相同的非空子集的方案数。
递推式:{mn}={m−1n−1}+m{mn−1} ,枚举将新元素放入一个新子集或放入之前的子集中得到。
通项公式:{mn}=∑i=0mi!(m−i)!(−1)m−iin 。
证明:我们有 mn=∑i=0m{in}×i!×(im) 。(考虑其组合意义,左边表示 n 个不同球随意放进 m 个盒中的方案数,右边表示枚举非空盒子的数量 i 计算即可。)
显然我们考虑二项式反演,设 gi=in ,fi={in}i! ,有 gm=∑i=0m(im)fi ,则
fm{mn}×m!{mn}=i=0∑m(−1)m−i(im)gi=i=0∑m(−1)m−ii!(m−i)!m!in=i=0∑mi!(m−i)!(−1)m−iin
另一种写法 {mn}=∑i=0mi!(m−i)!(−1)i(m−i)n 。
所以我们得到了求同一行第二类斯特林数 {in} 的方法,直接按照递推式卷积一下即可,时间复杂度 O(nlogn) 。
根据上面我们还可以得到自然数幂求和的一个推导:
i=0∑nik=i=0∑nj=0∑k{jk}×j!×(ji)=j=0∑k{jk}×j!×i=0∑n(ji)=j=0∑k{jk}×j!×(j+1n+1)
我们再从 EGF 的角度去研究第二类斯特林数,一个非空盒子装 i 个物品的方案数为 [i>0] ,对应的 EGF 为 F(x)=∑i=1∞i!xi ,其封闭形式为 ex−1 ,所以 k 个无标号非空盒子装 i 个物品对应的 EGF 为 k!(ex−1)k ,同时它也是同一列第二类斯特林数对应的 EGF ,即 ∑i=k∞{ki}i!xi=k!(ex−1)k 。
# 第一类斯特林数
第一类斯特林数,又叫斯特林轮换数。[mn] 表示将 n 个元素分为 m 个环的方案数(旋转前后相同的环视为一个环)
递推式: [mn]=[m−1n−1]+(n−1)[mn−1] ,枚举将新元素放入一个新环或插入一个旧环中得到。
性质: ∑i=1n[in]=n! ,每种排列对应每种置换。
# 上升幂与下降幂
下降幂 xn=(x−n)!x!=∏i=0n−1(x−i)
上升幂 xn=∏i=0n−1(x+i)
普通幂转下降幂 xn=∑i=0n{in}xi ,下降幂转普通幂 xn=∑i=0n[in](−1)n−ixi
普通幂转上升幂 xn=∑i=0n{in}(−1)n−ixi ,上升幂转普通幂 xn=∑i=0n[in]xi
现在证明第二个式子,我们利用归纳法
xn+1=(x−n)xn=(x−n)i=0∑n[in](−1)n−ixi=xi=0∑n[in](−1)n−ixi−ni=0∑n[in](−1)n−ixi=i=0∑n[in](−1)n−ixi+1−ni=0∑n+1[in](−1)n−ixi=i=1∑n+1[i−1n](−1)n−i+1xi+ni=1∑n+1[in](−1)n−i+1xi=i=1∑n+1([i−1n]+n∗[in])(−1)n−i+1xi=i=1∑n+1[in+1](−1)n−i+1xi=i=0∑(n+1)[in+1](−1)(n+1)−ixi
我们再证明第四个式子,利用第二个式子的结论,
xn=(−1)n(−x)n=i=0∑n[in](−1)n(−1)n−i(−x)i=i=0∑n[in](−1)n+n−i+ixi=i=0∑n[in]xi
# 斯特林反演
若 fk=∑i=0k{ik}gi ,则有 gk=∑i=0k(−1)k−i[ik]fi
斯特林反演与二项式反演相比不太常用,可以只做了解。
# 组合计数
# [NOIP2016 提高组] 组合数问题
题意:给定 n,m,k ,求对于所有的 0≤i≤n,0≤j≤min(i,m) 有多少对 (i,j) 满足 k∣(ji) 。
n≤2000 ,m≤2000 ,k≤21 。
直接 O(n2) 递推预处理所有组合数模 k 意义下的值,然后设 fi,j 表示 n=i,m=j 时对应的答案。考虑每拓展一次对答案的贡献,fi,j=fi−1,j−1+(fi−1,j−fi−1,j−1)+(fi,j−1−fi−1,j−1)=fi−1,j+fi,j−1−fi−1,j−1 ,同时判断 (ji) 的值是否为 0 ,若为 0 则 fi,j++ ,然后直接 dp 过去即可。时间复杂度 O(nm) 。
# [SDOI2016] 排列计数
题意:求有多少种 1 到 n 的排列 p 满足有恰好 m 个位置 pi=i 。答案对 109+7 取模。
n,m≤106 ,T≤5×105 。
考虑钦定这 m 个位置,有 (mn) 种情况。再考虑剩下的 (n−m) 个位置,由于恰好 m 个位置满足 pi=i ,所以剩下的这 (n−m) 个位置为错排,直接递推错排数公式 fi=(i−1)(fi−1+fi−2) ,初始化 f0=1,f1=0 。最终答案为 (mn)×fn−m 。时间复杂度为 O(n+T) 。
# [NOI Online #2 入门组] 建设城市
有 2n 座建筑,每座建筑的高度为 1 到 m 之间的正整数,要求前 n 座高度单调不降,后 n 座高度单调不升,且第 x 座和第 y 座的高度相同,求方案数模 998244353 后的结果。
1≤n,m≤105 ,1≤x<y≤2n
经典组合计数题,我们先分类讨论一下。
当 x≤n<y 时,我们枚举第 x 和第 y 座的高度 i ,此时序列会被分成 4 部分,以第一部分为例,它们高度区间为 [1,i] ,编号区间为 [1,x−1] 。即将 x−1 个相同的球放进 i 个盒子里的方案数,允许盒子为空,这就是经典的插板法了,易得答案为 (i−1x−1+i−1) ,同理我们能求出其它部分的方案数,乘起来即可。
再考虑当 x<y≤n 或 n<x<y 时,我们可以将 x 到 y 之间看成一个建筑,这样序列就被分成了两个部分,还是按照上面的插板法计算即可。最终时间复杂度为 O(n+m) 。
# [HAOI2011] Problem c
给 n 个人安排座位,每个人有一个编号 ai (编号可以相同)。从第一个人开始依次入座,第 i 个人先尝试坐到 ai ,如果 ai 被占了,就尝试 ai+1 ,ai+1 被占据了就尝试 ai+2 ,依次类推。如果一直尝试到第 n 个都不行,该安排方案就不合法。现在有 m 个人的编号已经确定,安排剩下的人的编号,求有多少种合法的安排方案,无解输出 NO,有解输出方案数对 mod 取模的结果。
T≤10 ,n≤300 ,0≤m≤n ,2≤mod≤109
先考虑无解的情况,我们设 sumi 表示已经确定的人中编号 ≥i 的人数。枚举编号,若 sumi>n−i+1 ,说明一定有人尝试到第 n 个也没座位,此时无解。然后我们去考虑有解的方案数,我们考虑一个 dp ,设 fi,j 表示剩余人数中编号 ≥i 的人中已经确定 j 个人的方案数,我们枚举一个 k ,表示选择 k 人的编号为 i ,有转移 fi,j=∑k=0jfi+1,j−k×(kj)(0≤j≤n−sumi−i+1) ,最终答案为 f1,n−m 。时间复杂度 O(Tn3) 。
# [SHOI2015] 超能粒子炮・改
求 ∑i=0k(in) 的值,对质数 p=2333 取模。
T≤105 ,n,k≤1018
我们设 fn,k=∑i=0k(in) ,大力化简。
fn,k=i=0∑k(in)=i=0∑k(i/pn/p)×(imodpnmodp)=(0n/p)×i=0∑p−1(inmodp)+(1n/p)×i=0∑p−1(inmodp)+⋯+(k/pn/p)×i=0∑kmodp(inmodp)=(i=0∑p−1(inmodp)×j=0∑k/p−1(jn/p))+(k/pn/p)×i=0∑kmodp(inmodp)=fnmodp,p−1×fn/p,k/p−1+(k/pn/p)×fnmodp,kmodp
直接递归求解即可,并且由于 p 只有 2333 ,所以可以直接预处理 2333 以内的组合数以及 f 数组即可,对于 (k/pn/p) 直接 lucas 定理计算即可。时间复杂度为 O(p2+Tlogp2n) 。
# [CQOI2018] 交错序列
称一个 01 序列为交错序列,当且仅当序列中没有相邻的 1 。对于一个长度为 n 的交错序列,设 0 出现的次数为 x ,1 出现的次数为 y ,并给定非负整数 a,b ,则我们定义这个序列的特征值为 xa×yb 。求长度为 n 的所有交错序列的特征值之和对质数 mod 取模的结果。
1≤n≤107 ,0≤a,b≤45 ,mod≤108
我们考虑枚举序列中 1 的个数 i ,那么有 n−i 个 0 ,考虑插板法。有 n−i+1 个空位,填入 i 个 1 ,则方案数为 (in−i+1) ,同时根据 n−i+1≥i 得到 i≤⌊2n+1⌋ ,所以答案为 i=0∑⌊2n+1⌋(in−i+1)×ib×(n−i)a 。发现可以直接线性筛得到 ia,ib ,且 mod 为质数也可以通过求阶乘和阶乘的逆元求组合数。所以最终时间复杂度为 O(n) 。事实上这道题有更优秀的时间复杂度,这里不再介绍。
# luogu P4981 父子
多次询问 n 个点的有根树种类对 109+9 取模后的结果。
T≤104 ,n≤109
# Prufer 序列
Prufer 序列可以用来解决一些无根树计数的问题。
树转化为 Prufer 序列:每次从树上选出一个编号最小的叶子节点,然后将与该叶子节点相邻的节点的编号写入 Prufer 序列的末尾,然后从树上删掉这个叶子节点,循环这个步骤直到只剩下两个节点。这个过程可以用一个 set 维护度数为 1 的节点实现。
一些性质:一个 n 个节点的树对应长度为 n−2 的 Prufer 序列,Prufer 序列中某个数出现的次数就等于这个数对应的节点在原无根树中的度数减一。
Cayley 公式:n 个节点的有标号无根树有 nn−2 个。(根据 Prufer 序列易得)
推论:1. n 个节点的有标号有根树有 n×nn−2=nn−1 个。
2. 已知 n 个节点的度数为 d1,d2⋯dn ,这样的无根树有 ∏i=1n(di−1)!(n−2)! 个。
所以这道题答案为 nn−1 ,快速幂计算一下即可。时间复杂度为 O(Tlogn) 。
# [HNOI2004] 树的计数
一个 n 个节点的树,给定每个节点的度数 di ,问这样的树有多少种。
1≤n≤150 ,答案保证在 long long 范围内。
还是熟悉的 Prufer 序列。题意可以转化为:有 n−2 个位置,要放 n 个数,每个数占 di−1 个位置,问方案数。这就是一个简单的组合计数,ans=∏i=1n(di−1sum) ,其中 sum 表示剩余的位置数,预处理组合数即可。同时这个式子化简完就可以得到 ∏i=1n(di−1)!(n−2)! ,但是这么算要写高精度,所以不如原始式子。时间复杂度 O(n2) 。
# CF785D Anton and School - 2
给定一个长度为 n 的只由小括号组成的括号序列,问有多少个长度为偶数的子序列,满足前半部分均为 '(',后半部分均为 ')' 。
1≤n≤2×105
考虑枚举满足条件的子序列中最后一个 '(' 的位置,假设它左边有 a 个 '(' (包括它自己),右边有 b 个 ')' ,那么它对答案的贡献为 ∑i=0min(a−1,b−1)(ia−1)(i+1b) ,此时时间复杂度为 O(n2) ,考虑优化。发现这个东西有点像范德蒙德卷积:∑i=0k(ia)(k−ib)=(ka+b) ,所以我们转化一下。
当 min(a−1,b−1)=b−1 时,∑i=0b−1(ia−1)(b−i−1b)=(b−1a+b−1)=(aa+b−1)
当 min(a−1,b−1)=a−1 时,∑i=0a−1(a−1−ia−1)(i+1b)=∑i=0a(a−1−ia−1)(i+1b)=(aa+b−1)
综上所述,对答案贡献为 (aa+b−1) ,可以 O(n) 预处理,单次 O(1) 计算。时间复杂度为 O(n) 。
# luogu P7481 梦现时刻
设 fa,b=∑i=0b(ib)(an−i) ,求 i=1⨁mj=1⨁mfi,jmod998244353 的值。
1≤n≤109 ,1≤m≤5000
非常巧妙的一道推式子题,发现异或无法利用性质,故我们只能考虑递推出所有的 f 值。
fa,b=i=0∑b(ib)(an−i)=i=0∑b(ib−1)(an−i)+i=0∑b(i−1b−1)(an−i)=fa,b−1+i=0∑b−1(ib−1)(an−i−1)=fa,b−1+i=0∑b−1(ib−1)(an−i)−i=0∑b−1(ib−1)(a−1n−i−1)=fa,b−1+fa,b−1−i=0∑b−1(i+1b)(a−1n−i−1)+i=0∑b−1(i+1b−1)(a−1n−i−1)=2fa,b−1−i=1∑b(ib)(a−1n−i)+i=1∑b(ib−1)(a−1n−i)
我们为了和题目的式子对应,我们将后面两个 ∑ 各补上一个 i=0 的情况,我们会惊奇地发现:
ans=2fa,b−1−i=1∑b(ib)(a−1n−i)+i=1∑b(ib−1)(a−1n−i)=2fa,b−1−fa−1,b+fa−1,b−1+(i−1n)−(i−1n)=2fa,b−1−fa−1,b+fa−1,b−1
至此我们可以递推求出所有的 f ,然后我们考虑边界。发现 f0,x=∑i=0x(ix)=2x ,fx,0=(xn)=(n−x)!x!n! ,均可以 O(m) 预处理出来,然后递推求答案即可。时间复杂度 O(m2) 。
# 容斥原理 / 二项式反演
# 错排数
我们设 fn 表示恰好有 n 个位置错开,gn 表示最多 n 个位置错开。易知 gn 为全部的排列,即 gn=n! ,直接二项式反演得到 fn=∑i=0n(−1)n−i(in)gi=∑i=0n(−1)n−i(in)i! 。
# [HAOI2008] 硬币购物
题意:有 4 种硬币面值分别为 c1,c2,c3,c4 。共有 T 组询问,每次询问给定 lim1,lim2,lim3,lim4,tot ,询问在第 i 种硬币数量不大于 limi 的前提下凑出总价值为 tot 的方案数。
1≤T≤1000 ,1≤ci,limi,tot≤105
非常巧妙的一道题。考虑先做一个完全背包预处理出没有任何限制时凑出价值为 i 的方案数 fi 。对于四个限制,我们可以考虑经典容斥,没有限制减去一个限制加上两个限制减去三个限制再加上四个限制。以一个限制为例,我们需要减去使用超过 limi 个 ci 的方案数,那我们可以强制先用 (limi+1) 个 ci ,设剩下的价值为 p,那么 fp 都是不满足限制的,需要减去,剩下的情况同理计算即可。时间复杂度为 O(4n+16T) ,其中 n 表示 tot 的最大值。
# [CSP-S2019] Emiya 家今天的饭
题意:有 n 种烹饪方法和 m 种食材,每道菜对应一种烹饪方法和一种食材,并且用第 i 种烹饪方法和第 j 种食材做出的菜种类数为 ai,j 。求满足 1. 至少做一道菜 2. 每道菜的烹饪方法互不相同 3. 每种食材最多在一半的菜中使用 的搭配方案数对 998244353 取模的结果。
1≤n≤100 ,1≤m≤2000
很巧妙的一道计数 dp 。发现不符合食材限制的最多有一种,所以直接枚举这一种不符合的食材。所以考虑容斥,先计算总方案数,比较简单,设 si=∑j=1nai,j ,再设 fi,j 表示前 i 种菜中共选了 j 种食材的方案数,直接转移 fi,j=fi−1,j+si×fi−1,j−1 ,总方案数为 ∑i=1nfn,i 。然后考虑减去不符合限制的,假如当前枚举到不符合食材的是 p ,设 gi,j,k 表示前 i 行选了 p 食材 j 次,其他食材 k 次的方案数,根据选不选 p 食材直接转移 gi,j,k=gi−1,j,k+ai,p×gi−1,j−1,k+(si−ai,p)×gi−1,j,k−1 ,但这样时间复杂度为 O(mn3) ,考虑优化。发现 j,k 的具体值我们并不关心,只关心相对大小,所以我们设 gi,j 表示前 i 行选了 p 食材次数减不选的次数为 j 的方案数,转移为 gi,j=gi−1,j+ai,p×gi−1,j−1+(si−ai,p)×gi−1,j+1 ,但是由于第二维可能是负的,所以我们直接同时加上 n ,最后统计 ∑i=1ngn,n+i 就是要减去的情况。最终时间复杂度为 O(mn2) 。
# [HNOI2011] 卡农
在集合 S={1,2,3,⋯,n} 中选出 m 个无序子集,满足:(1) 所有的子集不能为空 (2) 不能存在两个完全相同的集合 (3) 在这 m 个子集中 1 到 n 每个元素出现的次数必须为偶数。求方案数对 108+7 取模的结果。
1≤n,m≤106
神仙计数题目。考虑先转化一下题意,有 2n−1 个数,分别为 1 到 2n−1 ,从中选 一个大小为 m 的无序子集,满足:这 m 个数均不相同且这 m 个数的异或和为 0 ,求方案数。我们考虑 dp ,设 fi 表示选了 i 个数时满足限制的有序集合的方案数。发现当我们确定 i−1 个数时,假设他们的异或和为 x ,那么我们第 i 个数就确定了为 x ,易知选前 i−1 个数的总方案数为 A2n−1i−1 。发现有不合法的情况,所以我们考虑容斥,发现当 x=0 时显然是不合法的,也就是说,前 i−1 个数已经构成了一种合法方案,所以要减去 fi−1 。然后考虑减去有重复数字的,假设在前 i−1 个数中第 j 个数为 x ,我们将第 j 个数删去后剩下 i−2 个数构成一种合法方案,并且 x 有 2n−1−(i−2) 种取值,且 j 有 i−1 种取值,所以不合法的方案有 fi−2×(i−1)×(2n−i+1) 种。最终总的转移式子为 fi=A2n−1i−1−fi−1−fi−2×(i−1)×(2n−i+1) 。最终 fm 得到的就是满足限制的有序集合方案数,由于题目要求无序,所以再除以 m! 即可。时间复杂度为 O(m+logn) 。
# [HAOI2018] 染色
给一个长度为 n 的序列 ,给每个位置染成 1 到 m 里的任意一种颜色。若有 k 种颜色恰好出现了 p 次,则会获得 wk 的愉悦度。对于所有可能的染色方案,求愉悦度对 1004535809 取模后的结果。
1≤n≤107 ,m≤105 ,p≤150
1004535809 为 NTT 模数,原根为 3 。
(常用 NTT 模数:469762049 998244353 1004535809 ,其原根均为 3 )
考虑设 fi 表示恰好 i 种颜色出现 p 次的方案数,gi 表示至少 i 种颜色出现 p 次的方案数。考虑求解 g 数组,先钦定有 i 种颜色出现 p 次,为 (im) 。此时还剩下 n−pi 个位置没有染色,把它们看成一个整体,考虑看成一个多重集全排列数,为 (p!)i(n−pi)!n! ,再考虑从剩余的 m−i 种颜色中任意选取填入 (n−pi) 个空位中,为 (m−i)n−pi 。最终 gi=(im)(p!)i(n−pi)!n!(m−i)n−pi ,然后上二项式反演。以下 lim=min(m,⌊pn⌋) ,
fkfk×k!=i=k∑lim(−1)i−k(ki)gi=i=k∑lim(−1)i−kk!(i−k)!i!gi=i=k∑lim(i−k)!(−1)i−kgi×i!
我们设 F(x)=∑i=0limi!(−1)ixi ,G(x)=∑i=0limi!gixi ,则 fk=k!1∑i=klimGiFi−k 。这是经典的差卷积形式,我们将 F 翻转得到 Fi=FTlim−i ,则 fk=k!1∑i=klimFTlim+k−iGi ,这样 lim+k−i=lim+k ,变成了常见的和卷积形式,此时也知道题目的模数用处何在了,直接 NTT 碾过去即可。时间复杂度为 O(mlogm) 。
# [JSOI2011] 分特产
将 m 种物品分给 n 个同学,每种物品有 ai 个。在每个同学至少分得一个物品的前提下,求方案数模 109+7 的结果。
1≤n,m≤1000 ,ai≤1000
我们设 fi 表示恰好 i 个同学没有物品,所以我们求的就是 f0 。恰好有点难求,考虑设 gi 表示至少 i 个同学没有物品的方案数。那我们钦定 i 个同学没有物品,为 (in) ,考虑处理剩下 n−i 个同学。对于第 j 种物品,我们将其全部分给 n−i 个人,这是经典的插板法,方案数为 (n−i−1aj+n−i−1) ,最终得到 gi=(in)∏j=1m(n−i−1aj+n−i−1) ,最后直接上二项式反演得到 fk=∑i=kn−1(−1)i−k(ki)gi ,所以 f0=∑i=0n−1(−1)igi ,时间复杂度为 O(n2) 。
# [TJOI2019] 唱、跳、rap 和篮球
有一个长度为 n 的数组,将其用 A,B,C,D 填充,不允许有空位置。现分别有 a,b,c,d 个 A,B,C,D ,求填充数组的方案数,使得不存在 pos 使得第 pos,pos+1,pos+2,pos+3 位依次为 A,B,C,D 。方案数对 998244353 取模。
n≤1000 ,a,b,c,d≤500
设 fi 表示恰好存在 i 个 pos 的方案数,我们要求的就是 f0 。直接上二项式反演,设 gi 表示至少存在 i 个 pos 的方案数,有 gk=∑i=klim(ki)fi ,则 f0=∑i=0lim(−1)igi 。现在考虑求解 gi ,我们还是钦定 i 个 pos 剩下的位置随便排列。考虑计算其方案数,我们把那 i 个连续长度为 4 的位置缩成一个位置,这样就有 n−3i 个位置,从中选 n−4i 个不为 pos 的区间即可,故方案数为 (n−4in−3i)=(in−3i) 。然后考虑剩下的位置随意排列,现在我们分别有 a−i,b−i,c−i,d−i 个 A,B,C,D ,用它们填入 n−4i 个空位,求方案数。我们可以枚举 A,B,C,D 的数量,这样就是一个多重集排列数,所以方案数为 ∑p=0a−i∑q=0b−i∑s=0c−i∑t=0d−i[p+q+s+t=n−4i]p!q!s!t!(n−4i)! ,发现这又是一个卷积形式,直接 NTT 即可。还有另外一种利用 EGF 的方法,我们分别写出它们的 EGF ,以 A 为例,其对应的 EGF 为 ∑j=0a−ij!xj ,将四个 EGF 直接卷积得到 F(x) ,则 [xn−4i]F(x) 为答案。最终总时间复杂度为 O(n2logn) 。
# ARC160D
求长度为 n ,总和为 m 的序列数,满足通过以下两种操作可以使它变成全 0 的序列。对 998244353 取模。
一:在序列中选一个元素使其值减去 k
二:在序列中选择连续 k 个位置,让每个位置上的数减去 1
1≤k≤n≤2000 ,1≤m≤1018
发现无解当且仅当 mmodk=0 。我们考虑将这两种操作转化成一个操作序列 B ,它的长度为 2n−k+1 ,对于 1≤i≤n ,Bi 表示对位置 i 进行操作一的次数;对于 n+1≤i≤2n+k−1 ,Bi 表示对以 i−n 开头的连续 k 个位置进行操作二的次数。同时序列 B 还要满足
i=1∑2n−k+1Bi=km∀n+1≤i≤2n−k+1,Bi<k
第二个限制是限制每个区间加 1 的次数。我们将其限制为 <k ,这样每个原序列就能对应唯一一种操作序列。我们现在只需要对序列 B 进行计数。
这是一个带上界的插板法。经典容斥,我们钦定至少有 i 个不满足限制的即强制让它们取 k ,其余任意,那么剩下的和就是 km−ik ,直接插板法即可。最终得到
ans=i=0∑n−k+1(−1)i(in−k+1)(2n−kkm−ik+2n−k)
# 推式子综合
# CF932E Team Work
求 ∑i=1n(in)×ik ,对 109+7 取模。
1≤k≤5000 ,1≤n≤109
开始推式子。
ans=i=1∑n(in)ik
发现当 i=0 时对答案没有贡献,所以直接改写
ans=i=0∑n(in)ik=i=0∑n(in)j=0∑k{jk}j!(ji)=j=0∑k{jk}j!i=0∑n(in)(ji)=j=0∑k{jk}j!i=0∑n(jn)(i−jn−j)=j=0∑k{jk}(jn)j!i=0∑n(i−jn−j)=j=0∑k{jk}(n−j)!n!2n−j
直接 O(k2) 递推预处理斯特林数计算即可,时间复杂度为 O(k2+klogn) 。
# [HEOI2016/TJOI2016] 求和
给定 n ,求 ∑i=0n∑j=0i{ji}×2j×j! 的值,对 998244353 取模。
1≤n≤105
开始推式子。
ans=i=0∑nj=0∑i{ji}×2j×j!
发现当 j>i 时对答案没有贡献,所以直接改写
ans=i=0∑nj=0∑n{ji}×2j×j!=j=0∑n2j×j!×i=0∑n{ji}=j=0∑n2j×j!×i=0∑nk=0∑jk!×(j−k)!(−1)k(j−k)i=j=0∑n2j×j!×k=0∑jk!×(j−k)!(−1)ki=0∑n(j−k)i
∑i=0nxi 可以利用等比数列求和公式化简为 x−1xn+1−1
ans=j=0∑n2j×j!×k=0∑jk!×(j−k)!(−1)ki=0∑n(j−k)i=j=0∑n2j×j!×k=0∑jk!(j−k−1)(j−k)!(−1)k[(j−k)n+1−1]
到这里就豁然开朗了,后面又是喜闻乐见的和卷积形式,直接 NTT 卷一下即可,时间复杂度为 O(nlogn) 。
# [国家集训队] Crash 的文明世界
给定一颗 n 个点的树,定义点 u 的指标值为 ∑i=1ndisu,ik ,求每个点的指标值对 10007 取模的结果。
1≤n≤5×104 ,1≤k≤150
经典套路,先将 k 次方转化。
ansu=i=1∑ndisu,ik=i=1∑nj=0∑k{jk}j!(jdisu,i)=j=0∑k{jk}j!i=1∑n(jdisu,i)
现在最主要的问题是如何求出 ∑i=1n(jdisu,i) ,利用组合数性质 (jdisu,i)=(jdisu,i−1)+(j−1disu,i−1) ,我们想到可以通过树形 dp 求出。设 fu,j 表示 u 的子树内 (jdisu,i) 的和,则 fu,j=∑v∈sonufv,j+fv,j−1 ,此时能求出以某个点为根时的答案了,若求所有点的答案,直接上换根 dp 即可。时间复杂度为 O(nk) 。
# CF1278F Cards
共有 m 张牌,其中一张为目标牌。现进行 n 次完全随机洗牌(即 m! 种排列等概率出现),每次洗完查看第一张牌是什么。设 x 为 n 次洗牌后第一张牌为目标牌的次数,求 xk 的期望值,对 998244353 取模。
n,m≤998244352 ,k≤5000
我们考虑枚举有多少次第一张牌为目标牌,然后大力推式子:
ans=i=0∑n(in)(m1)i(mm−1)n−iik=mn1i=0∑n(in)(m−1)n−ij=0∑k{jk}j!(ji)=mn1j=0∑k{jk}j!i=0∑n(m−1)n−i(in)(ji)=mn1j=0∑k{jk}j!(jn)i=0∑n(m−1)n−i(i−jn−j)=mn1j=0∑k{jk}j!(jn)i=0∑n−j(in−j)(m−1)n−j−i×1i=mn1j=0∑k{jk}j!(jn)mn−j=j=0∑k{jk}(n−j)!n!(m1)j
后面两项均可以 O(k) 预处理得到,可以 O(k2) 全部预处理斯特林数,或 O(klogk) 直接求同一行的斯特林数。时间复杂度为 O(k2) 或 O(klogk) 。
# CF961G Partitions
有 n 个物品,每个物品有一个权值 wi 。定义一个集合 S 的权值为 ∣S∣∑i∈Swi ,定义一种划分方案的权值和为划分出的所有集合的权值和。求将这 n 个物品划分为 k 个集合的所有方案的权值和,对 109+7 取模。
n,k≤2×105 ,wi≤109
我们先考虑从组合意义上去简单地做出这道题,我们发现权值的计算前面有系数 ∣S∣ ,我们考虑物品 j 对物品 i 的权值 wi 的贡献,为 j 和 i 分到同一个集合的方案数。当 j=i 为 {kn} ,当 j=i 时为 (n−1){kn−1} ,最终得到 ans=∑i=1nwi({kn}+(n−1){kn−1}) ,这样就可以直接利用通项公式求同一行第二类斯特林数,时间复杂度为 O(klogk) 。
虽然组合意义足以解决此题,但组合意义明显晦涩难懂一点,而代数推导才是我们想要的理解容易,所以我们从代数推导上再次解决此题。
我们发现每个物品对答案的贡献是相同的,我们设为 tmp ,我们考虑枚举 i 所在集合的大小 s ,我们此时要再选 s−1 个元素,同时还要将剩下的 n−s 个物品放入 k−1 个集合中,所以有 tmp=∑s=1ns(s−1n−1){k−1n−s} (别忘了贡献要乘集合大小 s ),开始推式子:
tmp=s=1∑ns(s−1n−1){k−1n−s}=s=1∑ns(s−1n−1)i=0∑k−1i!(k−1−i)!(−1)i(k−1−i)n−s=i=0∑k−1i!(k−1−i)!(−1)is=1∑ns(s−1n−1)(k−1−i)n−s
第一个 ∑ 已经化简的足够了,我们单独考虑第二个 ∑ 。
我们有 m(mn)=n(m−1n−1) (直接把组合数拆阶乘形式可以得证),所以我们把它拆开,于是有:
temp=s=1∑ns(s−1n−1)(k−1−i)n−s=s=1∑n(s−1n−1)(k−1−i)n−s+s=1∑n(s−1)(s−1n−1)(k−1−i)n−s=s=1∑n(s−1n−1)(k−1−i)n−s+(n−1)s=1∑n(s−2n−2)(k−1−i)n−s
这两个东西有没有勾起你的记忆,直接上二项式定理得:
temp=(k−1−i+1)n−1+(n−1)(k−1−i+1)n−2=(k−i)n−2(k−i+n−1)
最终 tmp=∑i=0k−1i!(k−1−i)!(−1)i(k−i)n−2(k+n−i−1) ,最后再乘上每个物品的权值即可。利用线性筛预处理 in−2 可将时间复杂度做到 O(k) 。
# [省选联考 2020 A 卷] 组合数问题
给定一个 m 次多项式 F(x)=a0+ax+a2x2+⋯+amxm ,求
i=0∑nF(i)xi(in)(modp)
1≤n,x,p,ai≤109 ,m≤min(n,1000)
也许你已经直接开始推了,但你发现用以前的方法好像推不动,这道题我们用一点新科技:下降幂。
对于下降幂 mk=(m−k)!m! ,它与组合数相乘: mk(mn)=(m−k)!m!(n−m)!m!n!=(m−k)!(n−m)!(n−k)!(n−k)!n!=(m−kn−k)nk 。
那我们先将 F(x)=∑i=0maixi 改写成下降幂形式 F(x)=∑i=0mbixi ,再开始推式子:
ans=i=0∑nj=0∑mbjijxi(in)=i=0∑nxij=0∑mbj(i−jn−j)nj=j=0∑mnjbji=0∑nxi(i−jn−j)
后面这个组合数是不是一眼就有思路了,凑二项式定理!
ans=j=0∑mnjbji=0∑nxi(i−jn−j)=j=0∑mnjbjxji=0∑nxi−j(i−jn−j)1n−i=j=0∑mnjbjxj(x+1)n−j
现在我们要计算的只有 bi 了,考虑普通幂转下降幂的等式:
i=0∑maixi=i=0∑maij=0∑i{ji}xj=i=0∑mxij=i∑maj{ij}
所以 bi=∑j=imaj{ij} ,直接 O(m2) 递推第二类斯特林数即可。总时间复杂度为 O(m2) 。
# The end