Processing math: 100%

[总结] 第一类斯特林数

第一类斯特林数

[nm] ,将 n 个元素划分为 m 个圆排列的方案数。

递推

递推式可以枚举最后一个元素是否放一个新的排列:[nm]=[n1m1]+(n1)×[n1m]

下面用 s(n,m) 表示 [nm]

性质

n!=ni=0s(n,i)

证明:考虑其组合意义。一个排列唯一对应一个置换,而一个置换唯一对应一组轮换。比如排列 (1,5,2,3,4),就可以看作轮换组 [1][2,5,4][3]。如果两个排列不同,那他们对应的轮换中,必定有一个元素的下一个元素不同,故排列与轮换一一对应。所以等式右侧的式子就是有 0n 个轮换的方案数。

求法

现在要快速求出第一类斯特林数的某一行。

直接给出定义,s(n,) 这东西的生成函数等于 n1i=0(x+i),也就是 xn 次上升幂。

于是就可以分治NTT来求了,复杂度 O(nlog2n)。具体实现用vector比较好写。

当然也可以 O(nlogn)

Fn(x)=n1i=0(x+i),则F2n(x)=Fn(x)×Fn(x+n)

考虑如何用 Fn(x) 快速求出 Fn(x+n)

Fn(x)=n1i=0aixi

Fn(x+n)=ni=0ai(x+n)i=ni=0ai×ij=0Cjinijxj=ni=0xi×nj=iCijnjiaj=ni=0xi×nj=ij!i!(ji)!njiaj

所以设 Fn(x+n)=n1i=0bixi,ci=i!×ai,di=nii! ,那么

bi×i!=jcj×dji

d 翻转以后是一个标准的卷积式子,直接倍增就好了。

实现的小细节就是,如果当前长度 len 为奇数,不能除以 2,所以直接递归 len1 ,然后回来之后乘上 (x+len1) 就行了。

posted @ 2019-02-12 20:26  YoungNeal  阅读(3233)  评论(1)    收藏  举报
编辑推荐:
· 在 .NET 中使用内存映射文件构建高性能的进程间通信队列
· 一个 java 空指针异常的解决过程
· 揭开 SQL Server 和 PostgreSQL 填充因子的神秘面纱
· 没有调度器的协程不是好协程,零基础深入浅出 C++20 协程
· 别做抢活的导演:代码中的抽象层次原则
阅读排行:
· 今年失业的程序员兄弟姐妹们,你们都去干什么了?
· TinyEditor v4.0 alpha 版本发布:表格更强大,表情更丰富,上传体验超乎想象!
· .NET周刊【7月第2期 2025-07-13】
· 圆方树学习笔记 —— 一种关于点双连通分量的思考方式
· MySQL 17 如何正确地显示随机消息?
点击右上角即可分享
微信分享提示