zoukankan      html  css  js  c++  java
  • 组合数学学习笔记

    本文绝大部分内容来自《混凝土数学》

    在被多项式爆踩的时候,我偶然发现了《混凝土数学》这本书,然后兴冲冲入手,一看啥都不会,于是就只能在这里带着推推柿子,尝试理解理解,也方便以后复习。

    (本文略过了大部分对OI无用的芝士,可以放心食用)

    (顺带一提这略掉的东西可能还有点多)

    现在开始!

    I.下降幂与上升幂

    无限微积分的微分算子(mathrm{D})的意义是显式的

    [mathrm{D}f(x)=limlimits_{h ightarrow0}dfrac{f(x+h)-f(x)}{h} ]

    无限微积分的积分算子(int)的意义是隐式的

    [int f(x)mathrm{d}x=g(x)Leftrightarrowmathrm{D}g(x)=f(x) ]

    有限微积分的差分算子(Delta)的意义是显式的

    [Delta f(x)=f(x+1)-f(x) ]

    有限微积分的求和算子(sum)的意义是隐式的

    [sum f(x)delta x=g(x)LeftrightarrowDelta g(x)=f(x) ]

    有限微积分的定积分的(sum_a^bf(x))的意义是

    [sumlimits_{iin[a,b)cupmathbb{Z}}f(x) ]

    注意此处不一定有(a<b)。与无限微积分类似,必有(sum_a^bf(x)+sum_b^af(x)=0)


    与有限微积分可以配套使用的东西是下降幂

    它的定义是

    [x^{underline{m}}=sumlimits_{i=0}^{m-1}x-i ]

    另一种定义是

    [x^{underline{m}}=dfrac{x!}{(x-m)!} ]

    明显下一种定义更加普适,因为它也可以为指数是(0)或者负数的下降幂做出定义。但是上一种定义可以应用于实数下降幂

    例如

    [x^{underline{-1}}=dfrac{1}{x+1} ]

    我们将差分算子应用于下降幂

    [egin{aligned}Delta(x^{underline{m}})&=(x+1)^{underline{m}}-x^{underline{m}}\&=dfrac{(x+1)!}{(x-m+1)!}-dfrac{x!}{(x-m)!}\&=(x+1)dfrac{x!}{(x-m+1)!}-(x-m+1)dfrac{x!}{(x-m+1)!}\&=m imesdfrac{x!}{(x-m+1)!}\&=mx^{underline{m-1}}end{aligned} ]

    同微分算子应用于常规幂一致。

    同时将前缀和算子应用于下降幂也能得到优美的性质,即

    [oxed{sum_a^bx^{underline{m}}delta x=left.dfrac{x^{underline{m+1}}}{m+1} ight|_a^b} ]

    需要注意的是,该式在(m=-1)时有特例,即

    [oxed{sum_a^bx^{underline{-1}}delta x=sumdfrac{1}{x+1}=H_x|_a^b} ]

    其中(H_x=sumlimits_{i=1}^xdfrac{1}{x}),即调和级数。

    由此可见(H_x)(ln_x)的离散近似。

    (这也证明了为什么(sumlimits_{i=1}^ndfrac{n}{i})(O(nlog n))级别的,以及为什么有些离散的式子最终会产生调和级数出来)


    同有限微积分意义下的不动点(e^x)一样,无限微积分也存在这样的不动点。它是任何满足

    [Delta f(x)=f(x) ]

    的函数。

    上式等价于

    [f(x+1)-f(x)=f(x) ]

    [f(x+1)=2f(x) ]

    (f(x)=2^x)即可。即,(2^x)(e^x)在离散意义下的近似。

    而我们同时对于任意的(c),都有

    [Delta(c^x)=c^{x+1}-c^x=(c-1)c^x ]

    以及

    [sum_a^bc^kdelta x=dfrac{c^b-c^a}{c-1} ]

    (即等比数列求和公式)


    此外,还有一类上升幂,它的定义是

    [x^{overline{n}}=prodlimits_{i=0}^{n-1}x+i ]

    上升幂与下降幂按照如此方式联系在一起

    [x^{overline{n}}=(x+n-1)^{underline{n}} ]

    上升幂的应用较少,大部分的时候我们使用下降幂。

    II.二项式系数的基本应用

    定义1.

    [dbinom{n}{m}=dfrac{sumlimits_{i=0}^{m-1}n-i}{sumlimits_{i=1}^mi} ]

    定义2.

    [dbinom{n}{m}=dfrac{n!}{m!(n-m)!} ]

    定义3(扩展至实数域的定义):

    [oxed{dbinom{r}{k}=egin{cases}dfrac{r^{underline{k}}}{k!} (kgeq 0)\0(k<0)end{cases} Big(rinmathbb{R},kinmathbb{Z}Big)} ]

    事实证明,实数二项式系数在OI中并没有什么用处

    所以我们接下来将默认(n,minmathbb{N})

    吸收恒等式(非常重要,可以用来推式子):

    [oxed{dbinom{n}{m}=dfrac{n}{m}dbinom{n-1}{m-1}} ]

    它的兄弟们:

    [mdbinom{n}{m}=ndbinom{n-1}{m-1} ]

    [(n-m)dbinom{n}{m}=ndbinom{n-1}{m} ]

    杨辉三角形斜方向求和公式:

    [oxed{sumlimits_{k=0}^ndbinom{r+k}{k}=dbinom{r+n+1}{n}} ]

    (释义:从杨辉三角形坐标((r,0))的位置开始,向右下方(n)个位置的数之和,等于结尾位置下方的数的值)

    关于上指标求和公式:

    [oxed{sumlimits_{i=0}^ndbinom{i}{m}=dbinom{n+1}{m+1}} ]

    (释义:杨辉三角形中某一列前(n)个数的和,等于结尾位置右下角的数)

    而它的有限积分形式:

    [sumdbinom{x}{m}delta x=dbinom{x}{m+1}+C ]

    同时,它的有限微分形式

    [Deltadbinom{x}{n}=dbinom{x}{n-1} ]

    负整数的二项式系数的性质/上指标反转公式:

    [oxed{dbinom{r}{k}=(-1)^kdbinom{k-r-1}{k}} ]

    (如果你做过多项式学习笔记中XII.差分与前缀和那题的话,就会发现这正是我们打出差分系数的表后的结果——这就是负整数二项式系数的意义,差分系数

    行上交错系数求和:

    [oxed{sumlimits_{0leq kleq m}(-1)^kdbinom{r}{k}=(-1)^mdbinom{r-1}{m}} ]

    (释义:杨辉三角形中某一行前(n)个数中偶数位之和减去奇数位之和,等于结尾处上一格内的数)

    (这也解释了为什么杨辉三角形中某一行的所有奇位和等于所有偶位和——因为上一行的同一位置的数是(0)

    对于杨辉三角形中一行的前(m)个数之和没有封闭形式——

    但是加上一些奇奇怪怪的东西后它就可计算了。

    例如

    [sumlimits_{k=0}^m(dfrac{n}{2}-k)dbinom{n}{k}=dfrac{m+1}{2}dbinom{n}{m+1} ]

    (释义:杨辉三角形中第(n)行前(m)个数乘上它们到本行中点的距离之和,等于终点右方一个位置的值,乘上(m+1)的一半)

    奇怪的斜方向求和公式:

    [sumlimits_{k=0}^m2^{-k}dbinom{m+k}{k}=2^m ]

    吸收恒等式的一般形式:

    [oxed{dbinom{r}{m}dbinom{m}{k}=dbinom{r}{k}dbinom{r-k}{m-k}} ]

    二项式系数的推广,多项式系数:

    [dbinom{a_1+a_2+dots+a_m}{a_1,a_2,dots,a_m}=dfrac{(sum a_i)!}{prod a_i!}=prodlimits_{i=1}^mdbinom{sumlimits_{j=i}^ma_j}{sumlimits_{j=i+1}^ma_j} ]

    范德蒙德卷积公式

    [oxed{sumlimits_{k=0}^ndbinom{r}{k}dbinom{s}{n-k}=dbinom{r+s}{n}} ]

    换句话说,

    [C_r imes C_s=C_{r+s} ]

    其中(C_r)意为杨辉三角形第(r)行。


    下面我们来看一道二项式系数基本推式子示例。CF660E Different Subsets For All Tuples

    首先,空序列的 (m^n) 种可以单独计算。以下只考虑非空序列。

    我们考虑枚举一个 (i) 表示我们当前考虑的子序列长度为 (i)。再枚举一个 (jgeq i) 表示这第 (i) 个数填到了第 (j) 个位置。

    这时,子序列中前 (i-1) 个数就共有 (dbinom{j-1}{i-1}) 种位置的分配。

    同时,为避免重复计算,我们强制令此 (i) 个数都是子序列中前一个数后该值的首次出现。这意味着,此 (i) 个数每个都有 (m) 种填法,但剩余 (j-i) 个位置就只有 ((m-1)) 种填法了。此处共有 (m^i(m-1)^{j-i}) 种可能。

    然后,(i) 后面的东西随意填,共 (m^{n-j}) 种。

    全部怼一块,得到一个式子

    [sumlimits_{i=1}^nsumlimits_{j=i}^ndbinom{j-1}{i-1}m^{i}(m-1)^{j-i}m^{n-j} ]

    考虑交换枚举顺序,得到

    [sumlimits_{j=1}^nm^{n-j}sumlimits_{i=1}^jdbinom{j-1}{i-1}m^{i}(m-1)^{j-i} ]

    后面的式子看上去很熟悉。考虑提出一个 (m),并改为枚举 (i-1)

    [sumlimits_{j=1}^nm^{n-j+1}sumlimits_{i=0}^{j-1}dbinom{j-1}{i}m^{i}(m-1)^{j-i-1} ]

    看看,看看,后面不就是一个二项式展开的形式吗?还原回去,就得到

    [sumlimits_{j=1}^nm^{n-j+1}(2m-1)^{j-1} ]

    为让式子美观,改为枚举 (j-1)

    [sumlimits_{j=0}^{n-1}m^{n-j}(2m-1)^j ]

    到这里就可以直接 (O(n)) 计算了。

    代码戳这儿


    这里是一道比较综合的推式子例题:[NOI2019] 斗主地

    本题的关键是猜到一个结论:一次函数洗牌后期望仍是一次函数,二次函数洗牌后期望仍是二次函数。考虑证明。

    在证明之前,我们要先写出式子来。不妨设 (a_{1sim A}) 表示从顶至底第一堆的牌,(b_{1sim B}) 表示从顶至底第二堆的牌。

    考虑按照题意构造转移式。考虑第二堆的倒数第 (j) 张牌在洗牌后倒数第 (i+j) 个位置的情形。此时,第一堆的倒数前 (i) 张牌均已被洗入牌堆,且顺序与第二堆的前 (j-1) 张牌可以互换。故此种情形的概率为

    [dfrac{dbinom{i+j-1}{j-1}A^{underline i}B^{underline j}}{n^{underline{i+j}}} ]

    第一堆的倒数第 (i) 张牌洗牌后在第 (i+j) 个位置的情形也可以类似得到。故若设洗牌后的数组是 (c),则有

    [c_{k}=sumlimits_{i+j=n-k+1}dfrac{dbinom{i+j-1}{j-1}A^{underline i}B^{underline j}}{n^{underline{i+j}}} imes b_{B-j+1}+dfrac{dbinom{i+j-1}{i-1}A^{underline i}B^{underline j}}{n^{underline{i+j}}} imes a_{A-i+1} ]

    唔,看着好乱。

    稍微整理一下吧,我们首先决定把式子换成 (c_i=sumlimits_jdots) 的形式,然后把后面一大坨与 (A) 有关的提到前面来。

    [c_i=sumlimits_{j=1}^Aa_jdfrac{dbinom{i-1}{j-1}A^{underline j}B^{underline{i-j}}}{n^{underline i}}+sumlimits_{j=1}^Bb_jdfrac{dbinom{i-1}{j-1}A^{underline{i-j}}B^{underline j}}{n^{underline i}} ]

    一不做二不休,我们将其复原成原序列 ({a}) 中的情形。

    [c_i=sumlimits_{j=1}^Aa_jdfrac{dbinom{i-1}{j-1}A^{underline j}(n-A)^{underline{i-j}}}{n^{underline i}}+sumlimits_{j=1}^{n-A}a_{A+j}dfrac{dbinom{i-1}{j-1}A^{underline{i-j}}(n-A)^{underline j}}{n^{underline i}} ]

    好像也没简单多少……

    不过,因为两半的格式类似,考虑从前一半先动手处理。

    [egin{aligned}&sumlimits_{j=1}^Aa_jdfrac{dbinom{i-1}{j-1}A^{underline j}(n-A)^{underline{i-j}}}{n^{underline i}}\=&sumlimits_{j=1}^Aa_jdfrac{dbinom{i-1}{j-1}dfrac{A!}{(A-j)!}dfrac{(n-A)!}{(n-A-i+j)!}}{dfrac{n!}{(n-i)!}}\=&sumlimits_{j=1}^Aa_jdbinom{i-1}{j-1}dfrac{A!(n-A)!}{n!}dfrac{(n-i)!}{(A-j)!(n-A-i+j)!}\=&sumlimits_{j=1}^Aa_jdfrac{dbinom{i-1}{j-1}dbinom{n-i}{A-j}}{dbinom{n}{A}}end{aligned} ]

    看上去明显精悍了许多。

    发现,对于常规的 ({a}),化简应该不能继续下去了;但是因为期望具有线性性,即 ( ext E(x+y)= ext Ex+ ext Ey),所以我们可以将 ({a}) 拆成一些合适的数列的和,若这些数列每一个都满足洗牌后仍是一次/二次函数的限制,则 ({a}) 也一定满足。

    看着那一坨坨的组合数,我们便考虑下降幂:(a_i=(i-1)^{underline k}),其中 (k) 是一个常数。明显,通过取不同的 (k) 并求和,一切 ({a}) 都可以被表示。(证明?明显 (k=0sim n-1) 得到的数列线性无关(零的数量两两不同),故其张成的数列空间等于全集)

    那为啥选 ((i-1)^underline k) 而不是 (i^underline k) 呢?因为我们看到那个组合数里有个 (j-1) 所以就想把它搞掉。

    [egin{aligned}&sumlimits_{j=1}^Aa_jdfrac{dbinom{i-1}{j-1}dbinom{n-i}{A-j}}{dbinom{n}{A}}\=&sumlimits_{j=1}^A(j-1)^{underline k}dfrac{dbinom{i-1}{j-1}dbinom{n-i}{A-j}}{dbinom{n}{A}}\=&sumlimits_{j=1}^Adfrac{k!dbinom{j-1}{k}dbinom{i-1}{j-1}dbinom{n-i}{A-j}}{dbinom{n}{A}}\=&sumlimits_{j=1}^Adfrac{k!dbinom{i-1}{k}dbinom{i-k-1}{j-k-1}dbinom{n-i}{A-j}}{dbinom{n}{A}}& ext{(吸收恒等式)}end{aligned} ]

    此时,我们发现可以去掉 (j) 的限制,因为 (j>A) 时最后一个二项式系数为 (0)(j<1) 时倒数第二个二项式系数为 (0)。于是将常数提到开头并换成枚举 (j-k-1)

    [egin{aligned}&sumlimits_{j=1}^Adfrac{k!dbinom{i-1}{k}dbinom{i-k-1}{j-k-1}dbinom{n-i}{A-j}}{dbinom{n}{A}}\=&dfrac{k!dbinom{i-1}{k}}{dbinom{n}{A}}sumlimits_jdbinom{i-k-1}{j}dbinom{n-i}{A-k-1-j}\=&dfrac{k!dbinom{i-1}{k}}{dbinom{n}{A}}dbinom{n-k-1}{A-k-1}& ext{(范德蒙德卷积)}\=&(i-1)^underline k imesdfrac{dbinom{n-k-1}{A-k-1}}{dbinom{n}{A}}end{aligned} ]

    乘号后面的一大坨是与 (i) 无关的常数,可以看作是 (a_i ightarrow ta_i)。则,一 (k) 次下降幂多项式洗牌后变成了次数不大于 (k) 的多项式,则一堆次数不超过 (m) 的下降幂多项式之和洗牌后次数也不会大于 (m),也即任一多项式洗牌后次数不大于原本次数。证毕。

    代码戳这儿


    二项式系数的另一基本推论是卡特兰数。其是一经典数列,有着 (n) 个节点的二叉树、(n) 个数的入栈序列、长度为 (2n) 的括号序列等一系列实际意义。但是,一个最经典的模型,却是从点 ((0,0)) 走到 ((2n,0)),其中每步可以向右上/右下走一步,但全程不能到 (x) 轴以下的方案数。

    其通项公式是 (C(n)=dbinom{2n}{n}-dbinom{2n}{n-1})。该式子可以用全部方案减去不合法(即到 (x) 轴以下)的路径来得到。具体而言,全部路径数显然是 (dbinom{2n}n);而不合法路径,我们就在其第一次到达 (x) 轴以下时,关于直线 (y=-1) 翻转整个后半条路径,这样便得到了终点是 ((2n,-2)) 的全体路径。明显每一条这种路径与全体不合法的路径是一一对应的;而到达点 ((2n,-2)) 的路径数又是 (dbinom{2n}{n-1}),因而得证。

    下面我们来看一道应用:CF1204E Natasha, Sasha and the Prefix Sums

    这种加一减一前缀和的形式刚好就和我们前面的右上右下移动的模型相同。我们考虑设 (f(i)) 表示全程不到直线 (y=i) 以上的方案数。显然其可以直接用我们上述的翻转模型直接得出。而对其进行差分,就得到最大值恰为 (i) 的方案数。时间复杂度 (O(n+m))

    代码戳这儿

    III.高阶差分与牛顿展开

    高阶差分算符(Delta^n)的定义:

    [oxed{Delta^nf(x)=sumlimits_{k=0}^ndbinom{n}{k}(-1)^{n-k}f(x+k)} ]

    它的证明可以通过定义移位算符(mathrm{E}f(x)=f(x+1))以及恒等算符(mathrm{1}f(x)=f(x))得出:

    [Delta=mathrm{E}-mathrm{1} ]

    所以

    [Delta^n=(mathrm{E}-1)^n=sumlimits_kdbinom{n}{k}mathrm{E}^k(-1)^{n-k} ]

    (mathrm{E^k})就是位移(k)位符。

    我们设一个(d)次多项式

    [f(x)=sumlimits_{i=0}^da_ix^i ]

    它可以被唯一地表示成

    [f(x)=sumlimits_{i=0}^db_ix^{underline{i}} ]

    的形式。

    依据二项式系数的定义((dbinom{n}{m}=dfrac{n^{underline{m}}}{m!})),我们可以将其转成

    [f(x)=sumlimits_{i=0}^di!b_idbinom{x}{i} ]

    我们令(c_i=i!b_i),于是就有

    [f(x)=sumlimits_{i=0}^dc_idbinom{x}{i} ]

    从而我们可以用二项式系数的倍数之和表示任意多项式。我们称序列({c})为多项式(f)牛顿展开


    我们又有二项式系数的差分结果为

    [Deltadbinom{x}{i}=dbinom{x}{i-1} ]

    故应用牛顿展开,一个多项式的(k)阶差分可以很轻松地算出:

    [oxed{Delta^kf(x)=sumlimits_{i=0}^dc_idbinom{x}{i-k}} ]

    (x=0)时,我们有

    [Delta^kf(0)=egin{cases}c_k(kleq d)\0(k>d)end{cases} ]

    所以我们就有(c_k=Delta^kf(0)),即

    [oxed{f(x)=sumlimits_{i=0}^{infty}Delta^if(0)dbinom{x}{i}} ]

    (是不是跟泰勒展开挺像的?没错,这就是泰勒展开的离散近似)


    我们回到最初的式子

    [Delta^nf(x)=sumlimits_{k=0}^ndbinom{n}{k}(-1)^{n-k}f(x+k) ]

    代入(x=0),有

    [Delta^nf(0)=sumlimits_{k=0}^ndbinom{n}{k}(-1)^{n-k}f(k) ]

    又有

    [c_n=Delta^nf(0) ]

    所以

    [sumlimits_{k=0}^ndbinom{n}{k}(-1)^{n-k}f(k)=c_n ]

    我们又有

    [f(k)=sumlimits_{i=0}^kc_idbinom{k}{i} ]

    所以

    [sumlimits_{k=0}^ndbinom{n}{k}(-1)^{n-k}sumlimits_{i=0}^kc_idbinom{k}{i}=c_n ]

    两边同乘((-1)^n),就有

    [oxed{sumlimits_{k=0}^ndbinom{n}{k}(-1)^ksumlimits_{i=0}^kc_idbinom{k}{i}=(-1)^nc_n} ]

    因为牛顿展开系数必有(c_n=n!a_n),所以也可以对原本多项式建立这样的关系

    [oxed{sumlimits_{k=0}^ndbinom{n}{k}(-1)^ksumlimits_{i=0}^ka_ik^i=(-1)^nn!a_n} ]

    我们再来看牛顿展开式

    [f(x)=sumlimits_{i=0}^{infty}Delta^if(0)dbinom{x}{i} ]

    尝试把它变成同泰勒展开一致的格式,我们会发现它在位置(a)处的展开刚好是

    [oxed{f(a+x)=sumlimits_{i=0}^{infty}dfrac{Delta^if(a)}{i!}x^{underline{i}}} ]

    同泰勒展开

    [oxed{f(a+x)=sumlimits_{i=0}^{infty}dfrac{f^{(i)}(a)}{i!}x^i} ]

    一致。


    IV.二项式反演与错排问题

    简单介绍可以参见这里的LIII。

    详细推理见下。

    我们有

    [sumlimits_{k=0}^ndbinom{n}{k}(-1)^ksumlimits_{i=0}^kc_idbinom{k}{i}=(-1)^nc_n ]

    该式中(sumlimits_{i=0}^kc_idbinom{k}{i})一段的意义就是(f(k)),我们将其代入,得到

    [sumlimits_{k=0}^ndbinom{n}{k}(-1)^kf(k)=(-1)^nc_n ]

    我们发现这是一种已知(f),求(c)的好办法。

    我们设一个函数(g(x)=(-1)^nc_n),则就有

    [g(n)=sumlimits_{k=0}^ndbinom{n}{k}(-1)^kf(k) ]

    我们在知道(f)的情况下很容易求出(g),但是如果我们只知道(g)呢?

    我们考虑

    [sumlimits_{k=0}^ndbinom{n}{k}(-1)^kg(k) ]

    它等于

    [sumlimits_{k=0}^ndbinom{n}{k}(-1)^ksumlimits_{j=0}^kdbinom{k}{j}(-1)^jf(j) ]

    因为当(j>k)(dbinom{k}{j}=0),无影响,故扩大(j)的枚举范围

    [sumlimits_{k=0}^ndbinom{n}{k}(-1)^ksumlimits_{j=0}^ndbinom{k}{j}(-1)^jf(j) ]

    然后把(j)移到外面

    [sumlimits_{j=0}^nf(j)sumlimits_{k=0}^ndbinom{n}{k}dbinom{k}{j}(-1)^{k+j} ]

    调用吸收恒等式(dbinom{r}{m}dbinom{m}{k}=dbinom{r}{k}dbinom{r-k}{m-k}),我们有

    [sumlimits_{j=0}^nf(j)sumlimits_{k=0}^ndbinom{n}{j}dbinom{n-j}{k-j}(-1)^{k+j} ]

    然后移出来与(k)无关的项

    [sumlimits_{j=0}^nf(j)dbinom{n}{j}sumlimits_{k=0}^ndbinom{n-j}{k-j}(-1)^{k+j} ]

    改为枚举(k-j)

    [sumlimits_{j=0}^nf(j)dbinom{n}{j}sumlimits_{k=0}^ndbinom{n-j}{k}(-1)^{k+2j} ]

    ((-1)^{k+2j})显然可以去掉(2j),于是

    [sumlimits_{j=0}^nf(j)dbinom{n}{j}sumlimits_{k=0}^ndbinom{n-j}{k}(-1)^k ]

    后半段是一行中奇偶位的二项式系数之差,它只有在(n-j=0)时才为(1),所以

    [sumlimits_{j=0}^nf(j)dbinom{n}{j}[n-j=0] ]

    所以只需要保留(n=j)时的项即可;所以我们最终得到

    [g(n)=sumlimits_{k=0}^ndbinom{n}{k}(-1)^kf(k)Rightarrowsumlimits_{k=0}^ndbinom{n}{k}(-1)^kg(k)=f(n) ]

    它们的格式是对偶的,故反过来一样推的出来,故最终结果为

    [oxed{g(n)=sumlimits_{k=0}^ndbinom{n}{k}(-1)^kf(k)Leftrightarrow f(n)=sumlimits_{k=0}^ndbinom{n}{k}(-1)^kg(k)} ]

    它另外还有一个兄弟,就是

    [oxed{g(n)=sumlimits_{k=0}^ndbinom{n}{k}f(k)Leftrightarrow f(n)=sumlimits_{k=0}^ndbinom{n}{k}(-1)^{n-k}g(k)} ]

    证明和上面类似。


    二项式反演一般也可以从容斥角度理解。这就是式子中组合数以及(-1)的次幂的来历。


    二项式反演可以用来解决错排问题。用(D_n)表示(n)个人的错排数量。

    这里先插一嘴,它有一个递推公式(D_n=(n-1)(D_{n-1}+D_{n-2})),平常用这个就够了。

    则我们有

    [n!=sumlimits_{i=0}^ndbinom{n}{i}D_i ]

    它的含义是枚举所有排列中,恰好有(i)个失配的位置以及(n-i)个匹配的位置的方案数,并求和。

    我们如果取(g(n)=n!,f(n)=(-1)^nD_n)的话,就有

    [g(n)=sumlimits_{i=0}^ndbinom{n}{i}(-1)^if(i) ]

    反演得到

    [f(n)=sumlimits_{i=0}^ndbinom{n}{i}(-1)^ig(i) ]

    代入(f,g)的定义,则有

    [(-1)^nD_n=sumlimits_{i=0}^ndbinom{n}{i}(-1)^ii! ]

    到这里实际上已经可以(O(n))地求出单个(D_n)了。但是为了求出全部(D_n),我们还得继续优化。

    展开二项式系数,得到

    [(-1)^nD_n=sumlimits_{i=0}^ndfrac{n!}{i!(n-i)!}(-1)^ii! ]

    抵消掉一些东西

    [(-1)^nD_n=sumlimits_{i=0}^ndfrac{n!}{(n-i)!}(-1)^i ]

    换成枚举(n-i)

    [(-1)^nD_n=sumlimits_{i=0}^ndfrac{n!}{i!}(-1)^{n-i} ]

    ((-1)^n)移过去

    [D_n=sumlimits_{i=0}^ndfrac{n!}{i!}(-1)^{-i} ]

    显然有((-1)^{-i}=(-1)^i)

    [D_n=sumlimits_{i=0}^ndfrac{n!}{i!}(-1)^i ]

    最终得到

    [oxed{D_n=n!sumlimits_{i=0}^ndfrac{(-1)^i}{i!}} ]

    到这里就可以(O(n))一遍求出所有(D_n)了。

    这个公式的优势是可以在推式子时直接替代掉(D_n)


    下面我们来看一道例题:[MtOI2018]情侣?给我烧了!

    我们考虑如果设(n)对情侣两两不配对的情况数是(D_n)的话(注意这个(D_n)和错排的(D_n)不同),则恰有(k)对配对的方案数即为

    [dbinom{n}{k}n^{underline{k}}2^kD_{n-k} ]

    (dbinom{n}{k})意为从(n)个位置中选择(k)个作为配对的位置;(n^{underline{k}})是选择(k)对填入;(2^k)是因为每一对都有两种放法;(D_{n-k})是剩下部分的方案。

    现在我们考虑求出(D_n)

    我们假设每对情侣都是一男一女(没有歧视性取向独特者的意思),则我们考虑最靠前一排放什么:

    1. 两男/两女

    我们共有(2n(n-1))种方案选出两男/两女填入。则我们考虑它们的伴侣,则又有两种可能:

    A. 它们的伴侣坐在了一起:

    则此时方案数为((n-1)D_{n-2})

    B. 它们的伴侣没有坐在一起:

    则我们就可以把它们的伴侣撮合成一对以表示它们不能坐在一起(贵圈真乱),方案数为(D_{n-1})

    1. 一男一女(不是一对)

    我们仍有(2n(n-1))种方式选出它们;而对于它们的伴侣,仍然像之前那样分析即可。

    则分析下来,我们就有如下转移式:

    [D_n=4n(n-1)Big(D_{n-1}+(n-1)D_{n-2}Big) ]

    (O(n))预处理出所有(D_n),并代入(dbinom{n}{k}n^{underline{k}}2^kD_{n-k})中求值即可。

    本方法也可以通过[MtOI2018]情侣?给我烧了!(加强版)

    原版代码戳这儿

    加强版代码戳这儿


    又是一道例题Tokio Marine & Nichido Fire Insurance Programming Contest 2020E O(rand)

    乍一看可能会以为是 FMT 方向的题,但实际上不是,因为 FMT 只能处理一方的限制( AND 为定值或 OR 为定值),并不能同时处理。一个必要的观察是所有可能选择的 (x) 必定有 (S) 作为子集,且是 (T) 的子集。于是我们先舍弃那些不可能选到的 (x),然后对那些可能选择的 (x),舍弃其中在 (S,T) 中都选择的位和都未选择的位,这样就将问题转换到:选择一些数,使得它们的 AND(0)OR 为全集。

    这等价于它们在每一位上都不全相同。

    我们设 (f(x)) 表示恰有 (x) 位不相同的方案数,(g(x)) 表示至多 (x) 位不相同的方案数。则显然,有

    [g(x)=sumlimits_{i=0}^xdbinom{x}{i}f(i) ]

    因为我们要求的是 (f(| ext{fullset}|)),所以考虑二项式反演得到

    [f(x)=sumlimits_{i=0}^x(-1)^{x-i}dbinom{x}{i}g(i) ]

    现在考虑如何求解 (g)。我们设 (h(x)) 表示使得集合中所有数与 (x) 进行 AND 操作后均相等的集合数。显然这个可以枚举每个 (x),然后开个桶简单求解。然后,我们来考虑其实际意义——集合中所有数,在 (x) 有值的位置上均相等,在 (x) 无值的位置上可等可不等,故其所有集合中均至多有 (n-x) 位不相同;则 (g(x)=sumlimits_{|S|=x}h(S))。直接求解即可。

    代码戳这儿

    V.生成函数

    一个序列(left<a_0,a_1,dots ight>)普通生成函数(OGF)定义为

    [A(z)=sumlimits_{i=0}^{infty}a_iz^i ]

    我们记([z^n]A(z)=a_n),即(A(z))(n)次幂系数。

    我们将会发现一些神奇的恒等式,例如

    [(1+z)^n=sumlimits_{i=0}^{n}dbinom{n}{i}z^i ]

    (left<a_i=dbinom{n}{i} ight>)的生成函数是((1+z)^n)

    我们会发现

    [left<a_i=dbinom{r}{i} ight> imesleft<b_i=dbinom{s}{i} ight>=(1+z)^r imes(1+z)^s=(1+z)^{r+s} ]

    即范德蒙德卷积。

    另外,有两个奇怪的公式:

    [oxed{dfrac{1}{(1-z)^{n+1}}=sumlimits_{k=0}^{infty}dbinom{n+k}{n}z^k} ]

    因为左边可以被看作

    [(1-z)^{-n-1} ]

    然后就用二项式定理展开得到

    [sumlimits_{i=0}^{infty}dbinom{-n-1}{i}(-z)^i ]

    上指标反转得

    [sumlimits_{i=0}^{infty}(-1)^idbinom{n+i}{i}(-z)^i ]

    [sumlimits_{i=0}^{infty}dbinom{n+i}{i}z^i ]

    另一个奇怪的公式是

    [oxed{dfrac{z^n}{(1-z)^{n+1}}=sumlimits_{i=0}^{infty}dbinom{k}{n}z^k} ]

    通过前一个公式向右平移(n)位得到。


    OGF具体有什么意义呢?

    很明显一个数列的OGF的一般形式是多项式。既然是多项式,那就可以计算卷积。

    我们计算(f imes g),会发现

    [(fg)_{i+j}=sum f_ig_j ]

    也就是说,我们假如把(f_i)的意义看作是“有(f_i)种方式取出一个(i)”,则((fg)_i)的意义就是,有多少种方法从(f,g)中各取一个数,它们的和为(i)

    这个意义可以被应用于很多场景下,例如背包或者计数。


    这里我们来做一道例题:[国家集训队]整数的lqp拆分

    我们考虑设(f_{i,j})表示整数(i)拆分成(j)个数的结果。再设(F_i)表示斐波那契数列的第(i)项。

    则我们可以得到

    [f_{i,j}=sumlimits_{k=0}^jf_{i-1,k} imes F_{j-k} ]

    [f_i=f_{i-1} imes F ]

    而我们又有(f_0=1)

    故我们最终的结果就是

    [f_i=F^i ]

    然后我们要求的是

    [G=sumlimits_{i=0}^{infty}f_i=sumlimits_{i=0}^{infty}F^i ]

    套用等比数列求和,就是

    [dfrac{1-F^{infty}}{1-F} ]

    (F^{infty} ightarrow0),可以被忽略。故有

    [G=dfrac{1}{1-F} ]

    关于斐波那契数列的生成函数,它可以由递推式直接得出方程(F=xF+x^2F+1),然后解得

    [F=dfrac{1}{1-x-x^2} ]

    所以将(F)代入(G)的式子,就有

    [G=dfrac{1-x-x^2}{1-2x-x^2} ]

    稍加变化,就变成

    [G=dfrac{x}{1-2x-x^2}+1 ]

    显然后面那个(1)只与(G_0)的值有关,而我们并不关心(G_0)的值,故我们可以直接忽略那个(1),直接观察式子

    [dfrac{x}{1-2x-x^2} ]

    我们发现它的分母是个二次多项式,于是我们考虑把它化成

    [a imesdfrac{1}{1-cx}+b imesdfrac{1}{1-dx} ]

    的形式,因为后面那两个分式都可以被还原成等比数列的形式。

    为了做到这一点,我们考虑将上式的分母因式分解,得到

    [dfrac{x}{Big(1-(1-sqrt{2})xBig)Big(1-(1+sqrt{2})xBig)} ]

    则我们在上式中就有(c=1-sqrt{2},d=1+sqrt{2})。现在考虑求出(a)(b)

    我们有

    [a(1-dx)+b(1-cx)=x ]

    [aBig(1-(1+sqrt{2})xBig)+bBig(1-(1-sqrt{2})xBig)=x ]

    暴力拆开,得到

    [a-(a+sqrt{2}a)x+b-(b-sqrt{2}b)x=x ]

    因为右边没有常数项,故左边应有(a+b=0),即(a=-b)。代入得

    [-(a+sqrt{2}a)x+(a-sqrt{2}a)x=x ]

    [-2sqrt{2}ax=x ]

    因此有(a=-dfrac{1}{2sqrt{2}}=-dfrac{sqrt{2}}{4},b=-a=dfrac{sqrt{2}}{4})

    所以我们最终得到了

    [Big(-dfrac{sqrt{2}}{4}Big) imesdfrac{1}{1-(1-sqrt{2})x}+Big(dfrac{sqrt{2}}{4}Big) imesdfrac{1}{1-(1+sqrt{2})x} ]

    将分式还原成多项式形式,就有

    [ ext{ans}=-dfrac{sqrt{2}}{4} imes(1-sqrt{2})^n+dfrac{sqrt{2}}{4} imes(1+sqrt{2})^n ]

    (sqrt{2})(mod{10^9+7})下存在,为(59713600),故直接代入并使用快速幂求值即可。对于极大的(n)可以通过费马小定理优化。

    代码戳这儿


    一个序列(left<a_0,a_1,dots ight>)指数生成函数(EGF)定义为

    [hat{A}(z)=sumlimits_{i=0}^{infty}a_idfrac{z^i}{i!} ]

    它的命名是基于序列(left<1,1,dots ight>)的EGF

    [sumlimits_{i=0}^{infty}dfrac{z^i}{i!}=e^z ]

    我们考虑计算(widehat{fg}),有

    [(widehat{fg})_k=sumlimits_{i+j=k}dbinom{k}{i}hat{f}_ihat{g}_j ]

    证明可以通过暴力拆开组合数得到。

    就是因为有了这个组合数,EGF可以用来解决顺序问题。例如,AAA的EGF与BBBB的EGF,卷起来后得到的,是AAABBBB的字母的所有排列,而它们的OGF卷在一起就只能得到单独的AAABBBB


    下面我们来看一题:[TJOI2019]唱、跳、rap和篮球

    考虑二项式反演。我们设(f(i))表示钦定(i)个位置出现鸡你太美的方案数,(g(i))表示恰好出现(i)个鸡你太美的方案数。

    则我们有

    [f(i)=sumlimits_{j=i}^{infty}dbinom{j}{i}g(j) ]

    于是我们二项式反演得到

    [g(i)=sumlimits_{j=i}^{infty}(-1)^{j-i}dbinom{j}{i}f(j) ]

    因为我们要求的答案是(g(0)),所以就有答案等于

    [g(0)=sumlimits_{j=0}^{infty}(-1)^{j}dbinom{j}{0}f(j)=sumlimits_{j=0}^{infty}(-1)^{j}f(j) ]

    我们考虑(f(i))

    我们将一组鸡你太美共(4)个人缩成一个人,则共有(n-3i)个人。我们从中选出(i)个位置再把它展开成一组鸡你太美,则最终就有(dbinom{n-3i}{i})种不同的钦定方式。

    而剩下的部分可以随便填。我们令(F(n,a,b,c,d))表示(n)个位置随便乱填的方案数。则有

    [F(i)=dbinom{n-3i}{i}F(n-i,a-i,b-i,c-i,d-i) ]

    所以代回答案式,就有

    [sumlimits_{i=0}^{infty}(-1)^{i}dbinom{n-3i}{i}F(n-i,a-i,b-i,c-i,d-i) ]

    现在我们考虑求出(F(n,a,b,c,d))。应用我们之前EGF的芝士,我们发现如果令(U_k(x)=sumlimits_{i=0}^kdfrac{x^i}{i!})的话,它就是

    [Big(U_{a-i} imes U_{b-i} imes U_{c-i} imes U_{d-i}Big)_{n-i} ]

    所以我们NTT计算上式即可做到(O(n^2log n))

    但是我们还可以做的更好——我们令一个(F=U_{a-i} imes U_{b-i},G=U_{c-i} imes U_{d-i}),则我们要求的是((FG)_{n-i})。则我们如果从大往小枚举(i)的话,就会发现它们都是在上一个的基础上增加了一些东西。则我们可以(O(n))更新(F)(G),再(O(n))暴力计算((FG)_{n-i})(只要求出这一位上的值来)。则总复杂度即是(O(n^2))

    代码戳这儿


    这边又有一题[HAOI2018]染色

    或许你跟我一样,看到这里的“染色”的实质是排列后,就会条件反射地又想套EGF了。但是实际上这题使用EGF并不会很方便。

    我们还是先套用二项式反演。我们设(f_i)表示钦定(i)种颜色出现(s)次,剩下的随便填的方案数。再设(g_i)表示有且只有(i)种颜色出现(s)次的方案数。显然,(g)可以直接由(f)二项式反演得到。则我们只需要求出(f)即可。

    我们有

    [f_i=dbinom{m}{i}dfrac{n!}{(s!)^i(n-si)!}(m-i)^{n-si} ]

    其中二项式系数的意义是选择(i)种颜色;那个分数的意义是把未被钦定的其它颜色看作同一种颜色时的方案数(实际上它有个专门名称叫做“多项式系数”);而最后一个幂的意义是考虑未被钦定的颜色的填法。

    求出(f)后,(g)即可通过拆开组合数并翻转几次进行NTT得出。

    代码戳这儿

    VI.两类斯特林数

    第二类斯特林数(left{egin{matrix}n\kend{matrix} ight})的定义是将(n)个数分到(k)个非空集合的方案数。它的左右是集合符号({}),较为易记。

    它有如下的递推式

    [oxed{left{egin{matrix}n\kend{matrix} ight}=kleft{egin{matrix}n-1\kend{matrix} ight}+left{egin{matrix}n-1\k-1end{matrix} ight}} ]

    前一半的释义是第(n)个数随意放入前(k)个集合的方案数;后一半的释义是第(n)个数单独分一个集合的方案数。

    递推起始条件是

    [left{egin{matrix}0\0end{matrix} ight}=1 ]

    它有如下几条浅显的性质:

    • (left{egin{matrix}n\mend{matrix} ight})(m>n)时为(0);

    • (left{egin{matrix}n\0end{matrix} ight}=[n=0]);

    • (left{egin{matrix}n\1end{matrix} ight}=1);

    • (left{egin{matrix}n\2end{matrix} ight}=2^{n-1}-1);

    • (left{egin{matrix}n\nend{matrix} ight}=1)


    第一类斯特林数(left[egin{matrix}n\kend{matrix} ight])的定义是将(n)个数分为(k)轮换的方案数。

    其中“轮换”的定义是形如“A对应BB对应CC对应A“这样的东西。

    它有如下的递推式

    [oxed{left[egin{matrix}n\kend{matrix} ight]=(n-1)left[egin{matrix}n-1\kend{matrix} ight]+left[egin{matrix}n-1\k-1end{matrix} ight]} ]

    前一半的释义是第(n)个数随意插到前(n-1)个数中某一个数后面的方案数;后一半的释义是第(n)个数单独分一个轮换的方案数。

    递推起始条件仍是

    [left[egin{matrix}0\0end{matrix} ight]=1 ]

    它有如下几条浅显的性质:

    • (left[egin{matrix}n\mend{matrix} ight])(m>n)时为(0);

    • (left[egin{matrix}n\0end{matrix} ight]=[n=0]);

    • (left[egin{matrix}n\1end{matrix} ight]=(n-1)!);

    • (left[egin{matrix}n\nend{matrix} ight]=1)

    另外,显然有

    [left[egin{matrix}n\mend{matrix} ight]geqleft{egin{matrix}n\mend{matrix} ight} ]


    每一组排列都等价于一组轮换;所以必有

    [oxed{sumlimits_{k=0}^nleft[egin{matrix}n\kend{matrix} ight]=n!} ]

    第二类斯特林数与下降幂有很大的联系——准确地说,有公式

    [oxed{x^n=sumlimits_{k=0}^nleft{egin{matrix}n\kend{matrix} ight}x^{underline{k}}} ]

    该公式可以通过归纳法证出:

    显然当(n=0)时此式成立;

    假设(n-1)处上式成立;我们现在要推出(n)处也成立。

    则有

    [x^{n-1}=sumlimits_{k=0}^{n-1}left{egin{matrix}n-1\kend{matrix} ight}x^{underline{k}} ]

    两边同乘(x),有

    [x^n=xsumlimits_{k=0}^{n-1}left{egin{matrix}n-1\kend{matrix} ight}x^{underline{k}} ]

    又有

    [x imes x^{underline{k}}=x^{underline{k+1}}+kx^{underline{k}} ]

    则套用得

    [x^n=sumlimits_{k=0}^{n-1}left{egin{matrix}n-1\kend{matrix} ight}x^{underline{k+1}}+sumlimits_{k=0}^{n-1}left{egin{matrix}n-1\kend{matrix} ight}kx^{underline{k}} ]

    在第一个式子中改为枚举(k+1),就有

    [x^n=sumlimits_{k=1}^nleft{egin{matrix}n-1\k-1end{matrix} ight}x^{underline{k}}+sumlimits_{k=0}^{n-1}left{egin{matrix}n-1\kend{matrix} ight}kx^{underline{k}} ]

    因为奇奇怪怪的第一类斯特林数全都为(0),所以我们可以扩大枚举范围

    [x^n=sumlimits_{k=0}^nleft{egin{matrix}n-1\k-1end{matrix} ight}x^{underline{k}}+sumlimits_{k=0}^{n}left{egin{matrix}n-1\kend{matrix} ight}kx^{underline{k}} ]

    将两者合并,就是

    [x^n=sumlimits_{k=0}^nleft(kleft{egin{matrix}n-1\kend{matrix} ight}+left{egin{matrix}n-1\k-1end{matrix} ight} ight)x^{underline{k}} ]

    发现了什么?中间那一大坨就是(left{egin{matrix}n\kend{matrix} ight})

    所以我们最终得到

    [x^n=sumlimits_{k=0}^nleft{egin{matrix}n\kend{matrix} ight}x^{underline{k}} ]


    同理我们可以得出将上升幂转成一般幂的公式:

    [oxed{x^{overline{n}}=sumlimits_{k=0}^nleft[egin{matrix}n\kend{matrix} ight]x^k} ]

    而上升幂可以直接转成下降幂。

    所以我们最终可以得出普通幂转上升幂/下降幂的全套公式:

    [oxed{egin{matrix}x^n=sumlimits_{k=0}^nleft{egin{matrix}n\kend{matrix} ight}x^{underline{k}}\x^n=sumlimits_{k=0}^nleft{egin{matrix}n\kend{matrix} ight}(-1)^{n-k}x^{overline{k}}\x^{overline{n}}=sumlimits_{k=0}^nleft[egin{matrix}n\kend{matrix} ight]x^k\x^{underline{n}}=sumlimits_{k=0}^nleft[egin{matrix}n\kend{matrix} ight](-1)^{n-k}x^kend{matrix}} ]

    (关于啥时候要加((-1)^{n-k}),啥时候不加:牢记(x^{overline{n}}geq x^ngeq x^{underline{n}}),所以用大的展开小的的时候就要加上)

    这个重要的公式可以应用于例如[省选联考 2020 A 卷] 组合数问题这题。

    我们要求

    [sumlimits_{i=0}^nf(i)x^idbinom{n}{i} ]

    因为下降幂有这样一个优美的等式

    [i^{underline{j}}dbinom{n}{i}=n^{underline{j}}dbinom{n-j}{i-j} ]

    这个可以通过展开二项式系数得到。

    所以我们将(f(i)=sumlimits_{j=0}^ma_ji^j)转换为下降幂形式(f(i)=sumlimits_{j=0}^mb_ji^{underline{j}})

    就得到了

    [sumlimits_{i=0}^nsumlimits_{j=0}^mb_ji^{underline{j}}x^idbinom{n}{i} ]

    套用上面式子,我们得到

    [sumlimits_{i=0}^nsumlimits_{j=0}^mb_jn^{underline{j}}x^idbinom{n-j}{i-j} ]

    然后交换求和顺序,得到

    [sumlimits_{j=0}^mb_jn^{underline{j}}sumlimits_{i=0}^nx^idbinom{n-j}{i-j} ]

    显然当(i<j)时,(dbinom{n-j}{i-j})无意义。故我们改为枚举(i-j),就得到

    [sumlimits_{j=0}^mb_jn^{underline{j}}sumlimits_{i=0}^{n-j}x^{i+j}dbinom{n-j}{i} ]

    继续拆分

    [sumlimits_{j=0}^mb_jn^{underline{j}}x^jsumlimits_{i=0}^{n-j}x^idbinom{n-j}{i} ]

    我们可以直接在后面一重循环内部套用二项式定理,就得到了

    [sumlimits_{j=0}^mb_jn^{underline{j}}x^j(x+1)^{n-j} ]

    改变一下符号

    [sumlimits_{i=0}^mb_in^{underline{i}}x^i(x+1)^{n-i} ]

    完成!

    于是(O(m^2))地预处理第二类斯特林数并得出该多项式的下降幂表达,就可以(O(m))地求出上式。

    Bonus:标准多项式转下降幂多项式可以做到(O(mlog m)),但这暂时不是我们这里讨论的内容。

    代码戳这儿

    另外还有一道类似的题是CF1278F Cards,照着上面的结论推就完事了。代码戳这儿


    两类斯特林数的联系:

    [sumlimits_kleft{egin{matrix}n\kend{matrix} ight}left[egin{matrix}k\mend{matrix} ight](-1)^{n-k}=[m=n] ]

    以及

    [sumlimits_kleft[egin{matrix}n\kend{matrix} ight]left{egin{matrix}k\mend{matrix} ight}(-1)^{n-k}=[m=n] ]

    这被称作反转公式

    我们甚至可以对负的斯特林数做出定义——

    我们依然想要两类斯特林加法原理成立,即

    [left{egin{matrix}n\kend{matrix} ight}=kleft{egin{matrix}n-1\kend{matrix} ight}+left{egin{matrix}n-1\k-1end{matrix} ight} ]

    [left[egin{matrix}n\kend{matrix} ight]=(n-1)left[egin{matrix}n-1\kend{matrix} ight]+left[egin{matrix}n-1\k-1end{matrix} ight] ]

    则我们最终会发现有

    [left[egin{matrix}n\mend{matrix} ight]=left{egin{matrix}-m\-nend{matrix} ight} ]

    这种奇妙的对偶性。


    两类斯特林数行列上的求法:

    第二类斯特林数·行

    我们有一个公式

    [m!left{egin{matrix}n\mend{matrix} ight}=sumlimits_{j}dbinom{m}{j}(-1)^{m-j}j^n ]

    这个公式的左边的意义是将(n)个不同的球放入(m)个不同的盒子且不允许盒子为空的方案数。右边是在用容斥原理来表示相同意义——选出(j)个盒子,剩下(m-j)个盒子强制空置,然后每个球就有(j)种不同的放法,总共(j^n)种放法。

    我们将组合数拆开,得到

    [m!left{egin{matrix}n\mend{matrix} ight}=sumlimits_{j}dfrac{m!}{j!(m-j)!}(-1)^{m-j}j^n ]

    约一下就得到

    [left{egin{matrix}n\mend{matrix} ight}=sumlimits_{j}dfrac{j^n}{j!} imesdfrac{(-1)^{m-j}}{(m-j)!} ]

    计算卷积即可。

    代码戳这儿


    第一类斯特林数·行

    我们有递推式

    [x^{overline{n}}=sumlimits_{i}left[egin{matrix}n\iend{matrix} ight]x^i ]

    即第(n)行的第一类斯特林数的生成函数是(x^{overline{n}})

    我们现在考虑求出(x^{overline{n}})的标准幂形式。

    假设我们已知(x^{overline{n}})的标准幂,我们现在考虑求出(x^{overline{2n}})的标准幂。

    则有公式

    [x^{overline{2n}}=x^{overline{n}} imes(x+n)^{overline{n}} ]

    于是我们现在就要求出((x+n)^{overline{n}})的标准幂形式。

    设我们已经求出

    [x^{overline{n}}=sumlimits_{i}a_ix^i ]

    ((x+n))代入到上式中,得到

    [(x+n)^{overline{n}}=sumlimits_{i}a_i(x+n)^i ]

    二项式展开,得到

    [(x+n)^{overline{n}}=sumlimits_{i}a_isumlimits_{j}x^jn^{i-j}dbinom{i}{j} ]

    调换求和顺序

    [(x+n)^{overline{n}}=sumlimits_{j}x^jsumlimits_{i}a_in^{i-j}dbinom{i}{j} ]

    确定求和范围并重命名变量

    [(x+n)^{overline{n}}=sumlimits_{i=0}^{n}x^isumlimits_{j=i}^{n}a_jn^{j-i}dbinom{j}{i} ]

    拆开组合数

    [(x+n)^{overline{n}}=sumlimits_{i=0}^{n}x^isumlimits_{j=i}^{n}a_jn^{j-i}dfrac{j!}{i!(j-i)!} ]

    整理得

    [(x+n)^{overline{n}}=sumlimits_{i=0}^{n}dfrac{x^i}{i!}sumlimits_{j=i}^{n}a_jj!dfrac{n^{j-i}}{(j-i)!} ]

    我们设(a_i')表示((x+n)^{overline{n}})(i)次项系数,得到

    [sumlimits_{i=0}^na_i'x^i=sumlimits_{i=0}^{n}dfrac{x^i}{i!}sumlimits_{j=i}^{n}a_jj!dfrac{n^{j-i}}{(j-i)!} ]

    显然对应次数的项系数应该相等,故有

    [a_i'=dfrac{sumlimits_{j=i}^{n}a_jj!dfrac{n^{j-i}}{(j-i)!}}{i!} ]

    我们令

    [b_i=a_ii! ]

    [c_i=dfrac{n^{n-i}}{(n-i)!} ]

    计算卷积后,我们会发现

    [a_i'=dfrac{(bc)_{i+n}}{i!} ]

    这样我们就成功求出了((x+n)^{overline{n}})的标准幂表达。将其与(x^{overline{n}})卷在一起,就得到了(x^{overline{2n}})

    但是要倍增地求出斯特林数的话,还需要由(x^{overline{n}})推出(x^{overline{n+1}});这个可以直接乘上((x+n))得到,直接(O(n))手动卷积即可。

    则总复杂度(O(nlog n))

    代码戳这儿


    第二类斯特林数·列

    我们设

    [H_m=sumlimits_{i=0}left{egin{matrix}i\mend{matrix} ight}x^i ]

    套用第二类斯特林的递推式

    [left{egin{matrix}n\kend{matrix} ight}=kleft{egin{matrix}n-1\kend{matrix} ight}+left{egin{matrix}n-1\k-1end{matrix} ight} ]

    得到

    [H_m=sumlimits_{i=0}Bigg(mleft{egin{matrix}i-1\mend{matrix} ight}+left{egin{matrix}i-1\m-1end{matrix} ight}Bigg)x^i ]

    改为枚举(i-1),得到

    [H_m=xsumlimits_{i=0}Bigg(mleft{egin{matrix}i\mend{matrix} ight}+left{egin{matrix}i\m-1end{matrix} ight}Bigg)x^i ]

    拆开括号,得到

    [H_m=x(mH_m+H_{m-1}) ]

    继续拆,最终得到

    [H_m=dfrac{x}{1-xm}H_{m-1} ]

    我们已知(H_0=1)

    所以就有

    [H_m=prodlimits_{i=1}^{m}dfrac{x}{1-ix} ]

    [H_m=dfrac{x^m}{prodlimits_{i=1}^{m}1-ix} ]

    考虑如何求出(prodlimits_{i=1}^{m}1-ix)

    提出一个(x),得到

    [x^mprodlimits_{i=1}^{m}x^{-1}-i ]

    我们会发现它就等于翻转过来的(prodlimits_{i=1}^{m}x-i)

    而它又等于

    [dfrac{x^{underline{m+1}}}{x} ]

    所以我们只需要求出(x^{underline{m+1}})即可。

    而这个可以跟(x^{overline{m}})一样简单倍增得到。

    所以总结一下流程:

    1. 计算(x^{underline{m+1}})得到(a)

    2. 计算(dfrac{a}{x}),得到(b)

    3. 翻转(b),得到(c)

    4. 计算(c^{-1}),得到(d)

    5. 计算(x^md),得到答案。

    代码戳这儿


    第一类斯特林数·列

    我们这里固定了有(m)个轮换,所以考虑让轮换间变得有序,这样就最后在答案中除掉一个(m!)即可。

    考虑一个轮换的生成函数是(G=sumlimits_{i=1}^{infty}(i-1)!x^i);但是我们这里使用指数生成函数,则它的指数生成函数(hat{G}=sumlimits_{i=1}^{infty}(i-1)!dfrac{x^i}{i!}=sumlimits_{i=1}^{infty}dfrac{x^i}{i})

    现在我们考虑对两边求导,得到

    [hat{G}'=sumlimits_{i=1}^{infty}idfrac{x^{i-1}}{i}=sumlimits_{i=1}^{infty}x^{i-1}=sumlimits_{i=0}^{infty}x^i=dfrac{1}{1-x} ]

    然后再积分回去,就得到

    [hat{G}=intdfrac{1}{1-x}=lndfrac{1}{1-x} ]

    而我们最终的答案是(dfrac{hat{G}^m}{m!});所以直接多项式快速幂计算

    [Bigg(lndfrac{1}{1-x}Bigg)^m ]

    即可。

    (虽然实际应用时不需要计算(lndfrac{1}{1-x}),直接把它当作(sumlimits_{i=1}^{infty}dfrac{x^i}{i})处理即可)

    附带指出,本题极度卡常,请务必注意程序常数。

    代码戳这儿

    VII.欧拉数

    欧拉数(left<egin{matrix}n\mend{matrix} ight>)的定义是,(n)个数的排列中,恰存在(m)个位置使得(p_i<p_{i+1})(称为“升高”)的方案数。

    欧拉数具有如下性质:

    • (mgeq n)时,(left<egin{matrix}n\mend{matrix} ight>=0)

    显然一个排列最多只能有(n-1)个升高。

    • (left<egin{matrix}n\mend{matrix} ight>=left<egin{matrix}n\n-m-1end{matrix} ight>)(对称性)

    显然一个排列有(m)个升高,等价于它有(n-m-1)个降低,而升高和降低的方案数应是相同的。

    • (left<egin{matrix}n\mend{matrix} ight>=(m+1)left<egin{matrix}n-1\mend{matrix} ight>+(n-m)left<egin{matrix}n-1\m-1end{matrix} ight>)

    显然一个有(m)个升高的排列可以由以下两种方式得到:

    1. 在一个有(m)个升高但长度是(n-1)的排列中,往一个升高中间或者序列开头插入(n)。共(m+1)种方案。

    则此部分贡献是((m+1)left<egin{matrix}n-1\mend{matrix} ight>)

    1. 在一个有(m-1)个升高且长度是(n-1)的排列中,往一个降低中间或者序列末尾插入(n)。共(Big((n-1)-1-(m-1)Big)+1=(n-m))种方案。

    则此部分贡献是((n-m)left<egin{matrix}n-1\m-1end{matrix} ight>)


    一个非常非常重要的恒等式(Worpitzky恒等式

    (或许它可以被译作“沃皮茨基”恒等式?)

    [x^n=sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{x+k}{n} ]

    它可以被数学归纳法证明:

    显然当(n=0)时,有

    [x^0=left<egin{matrix}0\0end{matrix} ight>dbinom{x}{0}=1 ]

    (n>0)时,假设上式在(n-1)处成立,则我们有

    [x^{n-1}=sumlimits_kleft<egin{matrix}n-1\kend{matrix} ight>dbinom{x+k}{n-1} ]

    两边同乘(x),得到

    [x^n=xsumlimits_kleft<egin{matrix}n-1\kend{matrix} ight>dbinom{x+k}{n-1} ]

    我们这边有一个恒等式,即

    [xdbinom{x+k}{n}=(k+1)dbinom{x+k}{n+1}+(n-k)dbinom{x+k+1}{n+1} ]

    证明可以通过展开两边得到,即

    [xdfrac{(x+k)!}{n!(x+k-n)!}=(k+1)dfrac{(x+k)!}{(n+1)!(x+k-n-1)!}+(n-k)dfrac{(x+k+1)!}{(n+1)!(x+k-n)!} ]

    两边同乘((n+1)!(x+k-n)!),得到

    [x(n+1)(x+k)!=(k+1)(x+k-n)(x+k)!+(n-k)(x+k+1)! ]

    两边同除((x+k)!),得到

    [x(n+1)=(k+1)(x+k-n)+(n-k)(x+k+1) ]

    全部展开后就会发现全都抵消掉了,得证。

    回到上面的式子

    [x^n=xsumlimits_kleft<egin{matrix}n-1\kend{matrix} ight>dbinom{x+k}{n-1} ]

    (x)乘到右边的二项式系数上,套用刚才式子,就有

    [x^n=sumlimits_kleft<egin{matrix}n-1\kend{matrix} ight>Big[(k+1)dbinom{x+k}{n}+(n-k-1)dbinom{x+k+1}{n}Big] ]

    拆开得到

    [x^n=sumlimits_k(k+1)left<egin{matrix}n-1\kend{matrix} ight>dbinom{x+k}{n}+sumlimits_k(n-k-1)left<egin{matrix}n-1\kend{matrix} ight>dbinom{x+k+1}{n} ]

    在后一半中改为枚举(k+1),得到

    [x^n=sumlimits_k(k+1)left<egin{matrix}n-1\kend{matrix} ight>dbinom{x+k}{n}+sumlimits_k(n-k)left<egin{matrix}n-1\k-1end{matrix} ight>dbinom{x+k}{n} ]

    成了!只需要把后面的东西并一起就能得到

    [x^n=sumlimits_kBigg((k+1)left<egin{matrix}n-1\kend{matrix} ight>+(n-k)left<egin{matrix}n-1\k-1end{matrix} ight>Bigg)dbinom{x+k}{n} ]

    左边一大坨就是欧拉数的递推公式,所以我们最终就得到

    [x^n=sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{x+k}{n} ]

    证毕。


    那么这个东西可以干什么呢?

    它可以用来快速求出欧拉数。

    我们看到这题:排列计数

    题意很简单,求出所有的(left<egin{matrix}n\kend{matrix} ight>)

    我们想起来之前有一个式子

    [Deltadbinom{x}{n}=dbinom{x}{n-1} ]

    我们对其作(k)阶差分,就有

    [Delta^kdbinom{x}{n}=dbinom{x}{n-k} ]

    于是对于式子

    [x^n=sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{x+k}{n} ]

    我们两边同时作(m)阶差分,得到

    [Delta^mx^n=sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{x+k}{n-m} ]

    (x^n)(m)阶差分,运用高阶差分的定义

    [Delta^mx^n=sumlimits_{k}dbinom{m}{k}(-1)^{m-k}(x+k)^n ]

    所以

    [sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{x+k}{n-m}=sumlimits_{j}dbinom{m}{j}(-1)^{m-j}(x+j)^n ]

    代入(x=0),有

    [sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{k}{n-m}=sumlimits_{j}dbinom{m}{j}(-1)^{m-j}j^n ]

    对于右边一坨,我们套用在第二类斯特林数·行中使用的公式

    [m!left{egin{matrix}n\mend{matrix} ight}=sumlimits_{j}dbinom{m}{j}(-1)^{m-j}j^n ]

    因此就有

    [sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{k}{n-m}=m!left{egin{matrix}n\mend{matrix} ight} ]

    考虑两边同乘一个(z^{n-m}),得到

    [z^{n-m}sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{k}{n-m}=z^{n-m}m!left{egin{matrix}n\mend{matrix} ight} ]

    我们在两边同时对(m)求和,就有

    [sumlimits_{m}z^{n-m}sumlimits_kleft<egin{matrix}n\kend{matrix} ight>dbinom{k}{n-m}=sumlimits_mz^{n-m}m!left{egin{matrix}n\mend{matrix} ight} ]

    在左边交换枚举顺序,于是

    [sumlimits_kleft<egin{matrix}n\kend{matrix} ight>sumlimits_{m}z^{n-m}dbinom{k}{n-m}=sumlimits_mz^{n-m}m!left{egin{matrix}n\mend{matrix} ight} ]

    在左边使用二项式定理,得到

    [sumlimits_kleft<egin{matrix}n\kend{matrix} ight>(z+1)^k=sumlimits_mz^{n-m}m!left{egin{matrix}n\mend{matrix} ight} ]

    (z-1)代替(z),得到

    [sumlimits_kleft<egin{matrix}n\kend{matrix} ight>z^k=sumlimits_m(z-1)^{n-m}m!left{egin{matrix}n\mend{matrix} ight} ]

    在右边二项式展开((z-1)^{n-m}),得到

    [sumlimits_kleft<egin{matrix}n\kend{matrix} ight>z^k=sumlimits_mm!left{egin{matrix}n\mend{matrix} ight}sumlimits_{k}z^k(-1)^{n-m-k}dbinom{n-m}{k} ]

    这样我们就成功地把二项式系数扔到了另一边

    我们交换枚举顺序,得到

    [sumlimits_kz^kleft<egin{matrix}n\kend{matrix} ight>=sumlimits_{k}z^ksumlimits_m(-1)^{n-m-k}dbinom{n-m}{k}m!left{egin{matrix}n\mend{matrix} ight} ]

    显然(z^k)对应的系数应该全都相同,故应有

    [left<egin{matrix}n\kend{matrix} ight>=sumlimits_m(-1)^{n-m-k}dbinom{n-m}{k}m!left{egin{matrix}n\mend{matrix} ight} ]

    为美观,交换(k)(m)并整理得

    [oxed{left<egin{matrix}n\mend{matrix} ight>=sumlimits_kleft{egin{matrix}n\kend{matrix} ight}dbinom{n-k}{m}(-1)^{n-m-k}k!} ]

    这就是欧拉数的通项公式。

    为了变成卷积的形式,我们拆开二项式系数

    [left<egin{matrix}n\mend{matrix} ight>=sumlimits_kleft{egin{matrix}n\kend{matrix} ight}dfrac{(n-k) !}{m!(n-k-m)!}(-1)^{n-m-k}k!]

    将与各系数有关的项拆分

    [m!left<egin{matrix}n\mend{matrix} ight>=sumlimits_kleft{egin{matrix}n\kend{matrix} ight}(n-k)!k! imesdfrac{(-1)^{n-m-k}}{(n-m-k)!} ]

    所以我们令

    [f_i=left{egin{matrix}n\iend{matrix} ight}(n-i)!i! ]

    [g_i=dfrac{(-1)^{n-i}}{(n-i)!} ]

    则我们就有

    [m!left<egin{matrix}n\mend{matrix} ight>=sumlimits_{k}f_k imes g_{m+k} ]

    所以我们翻转(g)做卷积,即可得到翻转的(m!left<egin{matrix}n\mend{matrix} ight>)

    于是我们在求出第二类斯特林数后,就可以求出欧拉数了。

    代码戳这儿

  • 相关阅读:
    [摘]MongoDB范围查询的索引优化
    python ftp 暴破
    写mongodb日志
    [转]使用 Python 实现跨平台的安装程序
    HDOJ 1008 Elevator
    第一个数字
    反转串
    HDOJ 1108 最小公倍数
    HDOJ 1096 A+B for InputOutput Practice (VIII)
    报数游戏
  • 原文地址:https://www.cnblogs.com/Troverld/p/14621716.html
Copyright © 2011-2022 走看看