第一类斯特林数

概念

[ n k ] n \brack k [kn]表示将 n n n个数的序列划分为 k k k圆排列的方案数。

递推公式

[ n k ] = [ n − 1 k − 1 ] + [ n − 1 k ] × ( n − 1 ) {n \brack k}= {{n-1} \brack {k-1}}+{{n-1}\brack k}\times (n-1) [kn]=[k1n1]+[kn1]×(n1)
[ n − 1 k − 1 ] n-1 \brack k-1 [k1n1]表示将最后一个数单独创建一个圆排列的方案数

[ n − 1 k ] × ( n − 1 ) {n-1\brack k}\times (n-1) [kn1]×(n1)表示将最后一个数插入前面k个圆排列中的方案数。对每个圆排列,能插入的位置数即为圆排列的大小,所以总的插入位置数为n-1。

多项式表示

[ n k ] {n \brack k} [kn]为多项式 f n ( x ) = ∏ i = 0 n − 1 ( x + i ) f_n(x)=\prod_{i=0}^{n-1}(x+i) fn(x)=i=0n1(x+i) k k k次项系数。
比较好想:(不严格证明)
n = 1 n=1 n=1时显然成立。
n > 1 n>1 n>1时, f n ( x ) = ( x + n − 1 ) f n − 1 ( x ) = x ⋅ f n − 1 ( x ) + ( n − 1 ) f n − 1 ( x ) f_n(x)=(x+n-1)f_{n-1}(x)=x\cdot f_{n-1}(x)+(n-1)f_{n-1}(x) fn(x)=(x+n1)fn1(x)=xfn1(x)+(n1)fn1(x)
即,将 f n − 1 ( x ) f_{n-1}(x) fn1(x)右移一位,再加上自己的 ( n − 1 ) (n-1) (n1)倍,列个表出来看看。
  1 x x 2 x 3 . . . x ⋅ f n − 1   [ n − 1 0 ] [ n − 1 1 ] [ n − 1 2 ] . . . ( n − 1 ) f n − 1 ( n − 1 ) [ n − 1 0 ] ( n − 1 ) [ n − 1 1 ] ( n − 1 ) [ n − 1 2 ] ( n − 1 ) [ n − 1 3 ] . . . \begin{array}{c:c:c:c:c:c} \ &1&x&x^2&x^3&...\\\hdashline\\ x\cdot f_{n-1}&\ &{n-1\brack 0}&{n-1\brack 1}&{n-1\brack 2}&... \\\\\hdashline\\ (n-1)f_{n-1}&(n-1){n-1\brack 0}&(n-1){n-1\brack 1}&(n-1){n-1\brack 2}&(n-1){n-1\brack 3}&...\\\\\hdashline \end{array}  xfn1(n1)fn11 (n1)[0n1]x[0n1](n1)[1n1]x2[1n1](n1)[2n1]x3[2n1](n1)[3n1].........
对应竖着相加, x i x^i xi系数正好为 [ n − 1 i − 1 ] + ( n − 1 ) [ n − 1 i ] = [ n i ] {n-1\brack i-1}+(n-1){n-1\brack i}={n\brack i} [i1n1]+(n1)[in1]=[in]

倍增求Stirling

利用上面那个多项式,已经可以用分治FFT求出,时间复杂度 O ( n ⋅ log ⁡ 2 2 n ) O(n\cdot {\log_2}^2n) O(nlog22n)

还可以更优秀。
当我们求出 f n ( x ) = ∏ i = 0 n − 1 ( x + i ) f_n(x)=\prod_{i=0}^{n-1}(x+i) fn(x)=i=0n1(x+i),可以更快的求出 g n ( x ) = ∏ i = 0 n − 1 ( x + n + i ) g_n(x)=\prod_{i=0}^{n-1}(x+n+i) gn(x)=i=0n1(x+n+i)
这样可得 f 2 n ( x ) = f n ( x ) g n ( x ) f_{2n}(x)=f_n(x)g_n(x) f2n(x)=fn(x)gn(x)
f n ( x ) f_n(x) fn(x)已求出, f n ( x ) = ∑ i = 0 n a i ⋅ x i f_n(x)=\sum_{i=0}^na_i\cdot x^i fn(x)=i=0naixi
g n ( x ) = ∑ i = 0 n a i ( x + n ) i = ∑ i = 0 n ∑ j = 0 i a i ( i j ) n i − j x j = ∑ i = 0 n ∑ j = 0 i a i i ! ( i − j ) ! ⋅ j ! n i − j x j = ∑ j = 0 n x j j ! ∑ i = j n ( a i ⋅ i ! ) n i − j ( i − j ) ! = ∑ i = 0 n x i i ! ∑ j = 0 n − i ( a i + j ⋅ ( i + j ) ! ) n j j ! \begin{aligned} g_n(x)&=\sum_{i=0}^na_i(x+n)^i \\ &=\sum_{i=0}^n\sum_{j=0}^ia_i{i \choose j}n^{i-j}x^j\\ &=\sum_{i=0}^n\sum_{j=0}^ia_i{\frac {i!} {(i-j)!\cdot j!}}n^{i-j}x^j\\ &=\sum_{j=0}^n\frac {x^j} {j!}\sum_{i=j}^n({a_i}\cdot i!)\frac {n^{i-j}} {(i-j)!}\\ &=\sum_{i=0}^n\frac {x^i} {i!}\sum_{j=0}^{n-i}\big({a_{i+j}}\cdot (i+j)!\big)\frac {n^{j}} {j!} \end{aligned} gn(x)=i=0nai(x+n)i=i=0nj=0iai(ji)nijxj=i=0nj=0iai(ij)!j!i!nijxj=j=0nj!xji=jn(aii!)(ij)!nij=i=0ni!xij=0ni(ai+j(i+j)!)j!nj
后面一个求和式满足卷积的形式,将一个多项式设为 ∑ i = 0 n a i ( i + j ) ! ⋅ x i \sum_{i=0}^na_i(i+j)!\cdot x^i i=0nai(i+j)!xi,另一个多项式设为 ∑ i = 0 n n i i ! x n − i \sum_{i=0}^n\frac {n^i} {i!}x^{n-i} i=0ni!nixni,两多项式相乘,再左移n位即可。

于是我们可以倍增求解,每次求出 f n ( x ) f_n(x) fn(x),用 O ( n log ⁡ 2 n ) O(n\log_2n) O(nlog2n)的时间计算出 f 2 n ( x ) f_{2n}(x) f2n(x)
总时间复杂度为 T ( n ) = T ( n / 2 ) + O ( n log ⁡ n ) = O ( n log ⁡ n ) T(n) = T(n/2) + O(n\log n) = O(n\log n) T(n)=T(n/2)+O(nlogn)=O(nlogn)

一些能转换为第一类斯特林数的问题

1.求满足此条件排列的方案数:n个数的排列,有m个数满足,这个数在他的前缀中是最大的。
这m个数把n个数分成了m段,每段中,最大数一定在最前面,即每一段内的排列,只有相对位置不同,才算不同的排列,就是圆排列。所以方案数为 [ n m ] n\brack m [mn]
2.留坑。。。。。。。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值