zoukankan      html  css  js  c++  java
  • 两类斯特林数的整理

    定义

    第一类斯特林数(又称轮换数,by zzh),表示将(n)个不同的数分成(k)个无标号圆排列的方案数,用(egin{bmatrix}n\kend{bmatrix})表示,根据定义有如下递推式:

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

    边界条件为(egin{bmatrix}0\0end{bmatrix}=1)

    第二类斯特林数(又称集合数,by zzh),表示将(n)个不同的数分成(k)个无标号集合的方案数,用(egin{Bmatrix}n\kend{Bmatrix})表示,根据定义有如下递推式:

    [egin{Bmatrix}n\kend{Bmatrix}=egin{Bmatrix}n-1\k-1end{Bmatrix}+kegin{Bmatrix}n-1\kend{Bmatrix} ]

    边界条件为(egin{Bmatrix}0\0end{Bmatrix}=1)

    性质与快速求解

    我们往往只需要求解一行或一列的斯特林数,而上面两个递推式复杂度都是(O(n^2)),不甚理想,我们需要利用它们的一些优秀性质进行快速求解。

    按照从易到难的顺序进行求解。

    第二类斯特林数·行

    考虑组合意义,我们可以写出以下两个式子:

    [k^n=sum_{i=0}^kdbinom kiegin{Bmatrix}n\iend{Bmatrix}i! ]

    [k!egin{Bmatrix}n\kend{Bmatrix}=sum_{i=0}^k(-1)^{k-i}dbinom kii^n ]

    (k^n)可以理解为将(n)个有标号的物品放到(k)个有标号的盒子里,其中可以有盒子为空的方案数。我们考虑枚举哪些盒子为空,那么这两个式子是显然的。

    值得注意的是,式子中的(sum_{i=0}^k)可以替换成(sum_{i=0}^n),因为当(i>n)时有(egin{Bmatrix}n\iend{Bmatrix}=0),而当(i>k)时又有(dbinom ki=0),所以(i)只需要枚举到(min(n,k)),当然枚举到(n)(k)的任意一个都是可以的。

    细心一点可以发现,这两个式子其实就是(k!egin{Bmatrix}n\kend{Bmatrix})(k^n)构成的二项式反演关系。

    捎带的,我们可以利用(EGF)证一下这个反演:

    展开组合数,有

    [frac{k^n}{k!}=sum_{i=0}^kfrac{egin{Bmatrix}n\iend{Bmatrix}}{i!}*frac1{(k-i)!} ]

    [egin{Bmatrix}n\kend{Bmatrix}=sum_{i=0}^nfrac{(-1)^{k-i}}{(k-i)!}*frac{i^n}{i!} ]

    (P_n(x))({i^n})(EGF)(S_n(x))({i!egin{Bmatrix}n\iend{Bmatrix}})(EGF),那么根据两式可分别推出

    [P_n(x)=S_n(x)*e^x ]

    [S_n(x)=P_n(x)*e^{-x} ]

    所以两式等价。

    那么求法就很显然了:我们很容易求解(P_n(x))(e^{-x})的前(n+1)项,那么把它们卷起来就可以得到(S_n(x))了。

    第一类斯特林数·行&第二类斯特林数·列

    观察最初的递推式,你就会知道为什么这两个会有共同的方法了。不过你马上也会知道了

    通过递推式入手(顺便放了一个组合数以供对比参考):

    [dbinom nk=dbinom{n-1}{k-1}+dbinom{n-1}k ]

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

    [egin{Bmatrix}n\kend{Bmatrix}=egin{Bmatrix}n-1\k-1end{Bmatrix}+kegin{Bmatrix}n-1\kend{Bmatrix} ]

    (C_n(x))表示({dbinom nk})(OGF)(s_n(x))表示({egin{bmatrix}n\iend{bmatrix}})(OGF)(S_k(x))表示({egin{Bmatrix}i\kend{Bmatrix}})(OGF)(注意和行的区别),则有

    [C_n(x)=xC_{n-1}(x)+C_{n-1}=(1+x)C_{n-1}(x)=(1+x)^n ]

    [s_n(x)=xs_{n-1}(x)+(n-1)s_{n-1}=(x+n-1)s_{n-1}=prod_{i=0}^{n-1}(x+i)=x^{overline n} ]

    [S_k(x)=xS_{k-1}(x)+kxS_k(x)=frac{xS_{k-1}}{1-kx}=frac{x^k}{prod_{i=1}^k(1-ix)} ]

    这里可以看出第一类斯特林数其实就是展开上升幂之后对应项的系数。

    然后就得到了两个分治(ntt)的做法。

    不过第一个可以优化(第二个不知道行不行):在分治(ntt)的过程中,如果我们求出了上述式子的左边,我们可以想办法用左边去表示出右边来,而不用再递归下去。

    具体的,假如我们求出了左边(s_m(x)=x^{overline m}),那么右边其实就是(s_m(x+m)=(x+m)^{overline m}),对(s_m(x))(s_m(x+m))做卷积即可得到(s_{2m}(x))。顺带一提,有时候分治下去会碰到长度是奇数的情况,那么我们只需要让(s_{2m}(x))与二项式((x+2m))暴力乘起来就可以得到(s_{2m+1}(x))

    尝试对(s_m(x+m))进行展开:

    [s_m(x+m)=sum_{i=0}^megin{bmatrix}m\iend{bmatrix}(x+m)^i ]

    [=sum_{i=0}^megin{bmatrix}m\iend{bmatrix}sum_{j=0}^idbinom ijx^jm^{i-j} ]

    [=sum_{i=0}^mfrac{x^i}{i!}sum_{j=i}^megin{bmatrix}m\jend{bmatrix}j!*frac{m^{j-i}}{(j-i)!} ]

    把右边式子中的(egin{bmatrix}m\jend{bmatrix}j!)翻转一下,就可以得到一个卷积的形式,也就求出了(s_m(x+m))的各项系数,与(s_m(x))卷一下就可以得到(s_{2m}(x))。复杂度由分治降到了倍增。

    第一类斯特林数·列&第二类斯特林数·列

    你有没有发现,前面三个东西里面就二列是两个(log)的?

    所以它理应有更好的算法。

    我们从另一个角度考虑斯特林数的组合意义:

    可以发现,两类斯特林数都可以看做是某个东西的标号组合,一类是圆排列,二类是集合。那么,我们设(s_k(x))表示({egin{bmatrix}i\kend{bmatrix}})(EGF)(S_k(x))表示({egin{Bmatrix}i\kend{Bmatrix}})(EGF)(前面是(OGF)),(a(x))表示圆排列的(EGF)(A(x))表示集合的(EGF),则有

    [a(x)=sum_{i=1}^inftyfrac{x^i}i=ln(frac1{1-x}) ]

    [A(x)=sum_{i=1}^inftyfrac {x^i}{i!}=e^x-1 ]

    [s_k(x)=frac{a(x)^k}{k!} ]

    [S_k(x)=frac{A(x)^k}{k!} ]

    (s_k(x))(S_k(x))都除掉阶乘的原因是因为直接用圆排列或集合的(EGF)(k)次方的话含义是有(k)不同的圆排列或集合的组合,而斯特林数的定义中圆排列或集合是不带标号的,所以要除掉(k!)

    这样就可以在多项式快速幂的时间内求出两类斯特林数某一列的前(n)项。

    综上,全部四种情况的斯特林数均可在(O(nlogn))时间内求出,只不过常数越来越大。

    扩展

    斯特林反演

    [f_n=sum_{i=0}^negin{Bmatrix}n\iend{Bmatrix}g_iiff g_n=sum_{i=0}^n(-1)^{n-i}egin{bmatrix}n\iend{bmatrix}f_i ]

    不会证。

    贝尔数

    定义为将(n)个不同的数分成若干个无标号集合的方案,即(sum_{i=0}^negin{Bmatrix}n\iend{Bmatrix})

    看上去可以带到上面那个反演式子里面,然而并没有什么卵用。

    贝尔数是集合的任意标号组合,集合的(EGF)就是上面的(A(x)=e^x-1),那么贝尔数的(EGF)就是(exp(A(x))=exp(e^x-1))。我们接下来将从两方面来说明(exp)的含义,也就是它为什么代表任意标号组合。

    (F(x))为某种单个组合方案数的(EGF)(比如上面的集合),(G(x))为对这种单个组合再任意标号组合方案数的(EGF)(比如上面的贝尔数就是集合的组合)。

    首先是直接从定义式展开:

    [exp(F(x))=sum_{i=0}^infty frac{F(x)^i}{i!} ]

    可以看出,(i)个单个组合对应的贡献就是(frac{F(x)^i}{i!}),而(G(x))是单个组合的任意标号组合,所以就是把它们全部加起来。如果这个单个组合就是集合,那么(frac{F(x)^i}{i!})就是上面讲到的第二类斯特林数,而(exp(F(x)))是第二类斯特林数的和,也就是贝尔数。

    另一方面,我们可以枚举第一个物品放在多大的单个组合中,列出这样一个(dp)式子:

    [g_n=sum_{i=1}^ndbinom{n-1}{i-1}f_ig_{n-i}+[n=0] ]

    [frac{g_n}{(n-1)!}=sum_{i=1}^nfrac{f_i}{(i-1)!}frac{g_{n-i}}{(n-i)!} ]

    这样就得到了一个卷积的形式。我们发现(sum_{i=0}^infty g_{i+1}frac{x^i}{i!})其实就是(G(x)'),同理(sum_{i=0}^infty f_{i+1}frac{x^i}{i!})就是(F(x)'),那么就可以写成:

    [G(x)'=G(x)F'(x) ]

    [frac{G(x)'}{G(x)}=F'(x) ]

    [ln(G(x))+C=F(x)-f_0+C ]

    由于一般情况下(f_0=0)(就算不等于(0)也可以强制让它变成(0),因为(f_0)根本不会对答案有贡献),所以可以去掉常数(C)

    [ln(G(x))=F(x) ]

    [G(x)=exp(F(x)) ]

    得到了同样的结果。

    以此类推,森林的(EGF)也是树的(exp),沙漠的(EGF)也是仙人掌的(exp),第一类斯特林数的和——阶乘也是圆排列的(exp),这也是为什么上面写的圆排列的(EGF)(ln(frac1{1-x}))

    多项式(exp)的另一个用途是与多项式求(ln)组合应用,将多项式乘法转换成多项式加法,比如多项式快速幂和orzdkw,这里不细说了。

    应用

    1、求有(a)个前缀最大值和(b)个后缀最大值的(n)阶排列个数,(nleq10^5)

    每个前缀最大值和身后比它小的连续区间构成一个等价于圆排列的东西——都是固定一个数字,对其它数字做普通排列得到的结果。后缀最大值同理。那么问题就转换成有(n-1)个数字构成(a+b-2)个圆排列(最大值不参与构成圆排列)且选出(a-1)个圆排列放到最大值前面的方案,那么答案显然就是

    [egin{bmatrix}n-1\a+b-2end{bmatrix}dbinom{a+b-2}{a-1} ]

    随便怎么求了。

    2、求(sum_{i=0}^mdbinom mii^n,nleq10^5,mleq10^9)

    (i^n)用第二类斯特林数代换掉:

    [Ans=sum_{i=0}^mdbinom misum_{j=0}^ndbinom ijegin{Bmatrix}n\jend{Bmatrix}j! ]

    [=sum_{i=0}^negin{Bmatrix}n\iend{Bmatrix}i!sum_{j=0}^mdbinom mjdbinom ji ]

    [=sum_{i=0}^negin{Bmatrix}n\iend{Bmatrix}dbinom mii!sum_{j=i}^mdbinom{m-i}{j-i} ]

    [=sum_{i=0}^negin{Bmatrix}n\iend{Bmatrix}2^{m-i}m^{underline i} ]

    求出所有(egin{Bmatrix}n\iend{Bmatrix})即可。

    3、求(sum_{i=0}^mdbinom mif(i))(f(i))是一个(n)次多项式,(mleq10^9,nleq10^5)

    可以看出,这个题严格比上一题难。

    借鉴上一题的思路,我们想办法把答案凑成一个下降幂的形式。

    ({g_i})为满足(f(x)=sum_{i=0}^ng_ix^{underline i})的一组解,也就是把一个普通多项式(f(x))转成了一个下降幂多项式。这样的话,我们就可以用({g_i})代替第二类斯特林数,并依照上一题的方法求出答案:

    [Ans=sum_{i=0}^mdbinom mif(i) ]

    [=sum_{i=0}^mdbinom misum_{j=0}^ng_jdbinom ijj! ]

    [=sum_{i=0}^ng_i2^{m-i}m^{underline i} ]

    所以问题转换成如何求({g_i})

    观察这个式子:

    [f(x)=sum_{i=0}^ng_ix^{underline i}=sum_{i=0}^ng_idbinom xii! ]

    和第二类斯特林数·行那里提到的一个问题一样,因为当(i>n)(g_i=0)(i>x)(dbinom xi=0),所以(j)同样可以枚举到(x)(n)的任意一个,同时拆开组合数,就有

    [frac{f(x)}{x!}=sum_{i=0}^xg_i*frac1{(x-i)!} ]

    (F(x))({f{(i)}})(EGF)(G(x))({g_i})(OGF),有

    [F(x)=G(x)*e^x ]

    [G(x)=F(x)*e^{-x} ]

    因为(G(x))只有前(n+1)项有值,所以我们只要求出(F(x))的前(n+1)项,也就是所有的(f(i),iin[0,n]),这个可以多点求值做。

    要注意(f(x))表示的是一个多项式(f)(x)处的取值,而不代表生成函数。如果不好理解,可以在形式上把(f(i))换成(f_i),这样(F(x))就是({f_i})(EGF),看起来方便一些。

    4、给定一个(n*m)的矩阵,用(c)个不同的数字填满整个矩阵使得任意两行互不相同,任意两列互不相同,求方案数。(n,mleq10^5)

    首先钦定(n)是一个常数。

    如果只让行互不相同的话,方案数就是((c^m)^{underline n}),设其为(g_m)

    (f_m)表示行列都分别互不相同时的方案数,则有

    [g_m=sum_{i=0}^megin{Bmatrix}m\iend{Bmatrix}f_i ]

    上式的含义就是将(m)列分成(i)个集合,因为一个集合内部的列是相同的,所以可以把集合看成一列,方案数就是(f_i)

    根据斯特林反演,有

    [f_m=sum_{i=0}^m(-1)^{m-i}egin{bmatrix}m\iend{bmatrix}g_i ]

    斯特林数很好求,复杂度瓶颈在于如何求(g_i)。因为(g_i)是一个下降幂的形式,我们把它展开成为斯特林数后变成一个多项式:

    [x^{underline n}=sum_{i=0}^n(-1)^iegin{bmatrix}n\iend{bmatrix}x^i ]

    那么我们只要对所有(c^i)代入这个多项式求值即可。同样可以多点求值。

    5、原题比较复杂,简化一下,求(sum_{i=1}^nsum_{j=0}^ki^j-egin{Bmatrix}j\iend{Bmatrix}i!,nleq10^7,kleq10^9)

    当然了,由于简化导致变成了前后脱节的两部分。

    前面那部分可以直接等比数列求和,然后转成一个线性筛问题,主要是后面。

    (其实如果不看原题的话这里会难想一些,因为虽然本质一样的做法但思路有所区别)

    考虑到标号集合数和(n^k)构成的二项式反演,也就是

    [n^k=sum_{i=0}^ndbinom niegin{Bmatrix}k\iend{Bmatrix}i! ]

    我们是不是也可以把一列标号集合数一起用到这个反演里面呢?

    [sum_{i=0}^kn^i=sum_{i=0}^ksum_{j=0}^ndbinom njegin{Bmatrix}i\jend{Bmatrix}j!=sum_{i=0}^ndbinom nisum_{j=0}^kegin{Bmatrix}j\iend{Bmatrix}i! ]

    为了方便,我们设(f_n=sum_{j=0}^kegin{Bmatrix}j\iend{Bmatrix}i!,g_n=sum_{i=0}^kn^i)。也就是

    [g_n=sum_{i=0}^ndbinom nif_iiff f_n=sum_{i=0}^n(-1)^{n-i}dbinom nig_i ]

    那么答案就是

    [sum_{i=1}^ng_i-f_i ]

    (g_i)前面说过了,放到一边,我们主要看(f_i)

    [sum_{i=1}^nf_i ]

    [=sum_{i=1}^nsum_{j=0}^i(-1)^{i-j}dbinom ijg_j ]

    [=sum_{i=0}^ng_isum_{j=i}^n(-1)^{j-i}dbinom ji ]

    (w_i=sum_{j=i}^n(-1)^{j-i}dbinom ji),有

    [2w_i+(-1)^{n-i+1}dbinom{n+1}i=w_{i-1} ]

    至于为什么,自己画画,正负来回抵消就好了。

    备注

    给出一些可能用到的链接:

    模板

    第一类斯特林数·行

    第一类斯特林数·列

    第二类斯特林数·行

    第二类斯特林数·列

    多项式exp

    多项式多点求值

    普通多项式转下降幂多项式

    例题

    例题1

    例题2

    例题3(并没有,不过做一下那个板子就可以了)

    例题4(从别人那里扒下来的顺便加大了一下数据范围)

    例题5

  • 相关阅读:
    2.1命令行和JSON的配置「深入浅出ASP.NET Core系列」
    1.6部署到CentOS「深入浅出ASP.NET Core系列」
    1.5准备CentOS和Nginx环境「深入浅出ASP.NET Core系列」
    1.4部署到IIS「深入浅出ASP.NET Core系列」
    js匹配字符串去掉前面的0
    js遍历数组以及获取数组对象的key和key的值方法
    react-native-picker 打包报错verifyReleaseResources
    js排序——sort()排序用法
    node.js读取文件大小
    总结:将字符串转化json对象的三种方法:
  • 原文地址:https://www.cnblogs.com/star-city/p/11067126.html
Copyright © 2011-2022 走看看