第一类和第二类斯特林数
第一类斯特林数
第一类斯特林数定义如下:
\(s_1(n,k)\)表示\(n\)个元素组成\(k\)个圆排列的方案数。
其中\(n\)个元素的圆排列定义为\(n\)个元素围成一圈的排列,两个圆排列本质相同当且仅当两个圆排列以任意方式旋转之后相同。
那么我们可以得到第一类斯特林数的递推公式:
这个很好理解,第一项是第\(n\)个元素单独组成一个圆排列,第二项是不单独组成,那么我可以把第\(n\)个元素放在任意一个元素的左边(右边),这里左边和右边其实是等价的。
这样求出\(s_1(n,k)\)时空复杂度都是\(O(nk)\)的,但是我们还有更优秀的做法:
考虑下面这个生成函数:
其中\([x^k]F(x)\)就是\(s_1(n,k)\)。
这个可以对照着前面的递推方程感性理解,基本上就是每乘一次\((x+i)\)就表示从\(s_1(n,k)\)转移到\(s_1(n+1,k)\)。
那么我们就可以分治\(FFT\)优化到\(O(n\log^2n)\)。
好像还有一种倍增的\(O(n\log n)\)的做法先咕着以后再填。
例题:
[洛谷4609] [FJOI2016]建筑师,这个直接暴力递推就好了。
[CF960G] Bandit Blues,这个需要分治\(FFT\)。
第二类斯特林数
第二类斯特林数定义如下:
\(s_2(n,k)\)表示把\(n\)个不同的元素放到\(k\)个无差别的盒子的方案数。
那么很显然我们可以得到递推式:
复杂度\(O(nk)\)。
考虑一个比较有意思的东西,假设我们现在要算\(s_2(n,k)\),设\(f(i)\)表示至少\(i\)个盒子空着的方案数,\(g(i)\)表示恰好\(i\)个盒子空着的方案数。
那么我们可以得到:
对其广义容斥一下可得:
那么可以据此算出\(s_2\):
注意到这是个卷积的形式,所以我们可以在\(O(n\log n)\)的时间内求出\(s_2(n,i)\)的每一项,这里每一项指的是对于给定的\(n\),\(i\in [1,n]\)的每一项。
例题:
洛谷P4091 [HEOI2016/TJOI2016]求和,solution是很久以前写的了,不是很好看...还是放这里吧:sol。