斯特林数


tmp-Stirling

第二类斯特林数

定义

第二类斯特林数,用 $S(n,m)$ 或 $\begin{Bmatrix}n\\m\end{Bmatrix}$ 表示:将 $n$ 个有标号元素分为 $m$ 个非空无标号集合的方案数。

递推式

$$
\begin{Bmatrix}n\\m\end{Bmatrix}=\begin{Bmatrix}n-1\\m-1\end{Bmatrix} + m\times \begin{Bmatrix}n-1\\m\end{Bmatrix}
$$

通项公式

$$
\begin{Bmatrix}n\\m\end{Bmatrix}=\sum_{i=0}^{m} \frac{i ^ n(-1)^{m-i}}{i!(m-i)!}
$$

$n$ 固定,$m$ 变。

注意到通项公式很像卷积式,直接设:

$$
[n^i]g(n)=\dfrac{i^n}{i!}, [n^i]h(n)=\dfrac{(-1)^{i}}{i!}
$$

由于通项公式中 $i + (m-i) = m$,直接卷积得到 $f=g*h$.

Poly A, B;
A.a.resize(n+1), B.a.resize(n+1);
for(int i = 0; i <= n; i++) A.a[i] = power(i, n) * fac_inv[i] % mod;
for(int i = 0; i <= n; i++) B.a[i] = (i&1) ? mod - fac_inv[i] : fac_inv[i];
A = A * B;

TODO.

第一类斯特林数

定义

第一类斯特林数,用 $s(n,m)$ 或 $\begin{bmatrix}n\\m\end{bmatrix}$ 表示:将 $n$ 个有标号元素分为 $m$ 个非空无标号圆排列的方案数。

递推式

$$
\begin{bmatrix}n\\k\end{bmatrix}=\begin{bmatrix}n-1\\k-1\end{bmatrix}+(n-1)\begin{bmatrix}n-1\\k\end{bmatrix}
$$

https://www.luogu.com.cn/blog/oylyer/solution-p5408

记:

$$
F_n(x)=x^{\overline n}=\prod_{i=0}^n (x+i)
$$

则可证:

$$
x^{\overline n}=\sum_{i=1}^n \begin{bmatrix}n\\i\end{bmatrix} x^i
$$

由于显然有 $x^{\overline{2n}}=x^{\overline n}(x+n)^{\overline n}$,考虑分治求解。

$$
\begin{aligned}
F_n(x+n) &=\sum_{i=1}^n \begin{bmatrix}n\\i\end{bmatrix} (x+n)^i\\
&=\sum_{i=1}^n\begin{bmatrix}n\\i\end{bmatrix}\sum_{j=0}^i \binom{i}{j}x^jn^{i-j}\\
&=\sum_{i=1}^n\begin{bmatrix}n\\i\end{bmatrix}\sum_{j=0}^i \frac{i!}{j!(i-j)!}x^jn^{i-j}\\
&=\sum_{j=0}^n x^j \frac{1}{j!} \sum_{i=j}^n\begin{bmatrix}n\\i\end{bmatrix} i!\frac{n^{i-j}}{(i-j)!}\\
\end{aligned}
$$

设 $A_i=\begin{bmatrix}n\\i\end{bmatrix} i!$,$B_i=\dfrac{n^i}{i!}$,则原式化为:

$$
\begin{aligned}
F_n(x+n)
&=\sum_{j=0}^i x^j \frac{1}{j!} \sum_{i=1}^n\begin{bmatrix}n\\i\end{bmatrix} i!\frac{n^{i-j}}{(i-j)!}\\
&=\sum_{j=0}^i x^j \frac{1}{j!} \sum_{i=1}^n A_iB_{i-j}\\
\end{aligned}
$$

要凑卷积的形式,把 $B$ 翻转得到 $B^{\prime}_{n-i}=B_i$,则:

$$
\begin{aligned}
F_n(x+n)
&=\sum_{j=0}^i x^j \frac{1}{j!} \sum_{i=1}^n A_iB_{i-j}\\
&=\sum_{j=0}^i x^j \frac{1}{j!} \sum_{i=1}^n A_i{B^{\prime}}_{n+j-i}\\
\end{aligned}
$$

这样 $A*{B^{\prime}}$ 之后,得到的 $n+j$ 次项系数左移 $n$ 位,再整体 $\times \frac{1}{j!}$,就是 $F_n(x+n)$ 的 $j$ 次项系数。

再把 $F_n(x)*F_n(x+n)$,即可得到 $F_{2n}(x)$。

注意分治过程中,$F_{2n+1}=F_n(x)*F_n(x+n)*(x+2n)$,遇到奇数就手动乘上去即可。

void solve(int x) { //求f(x)
	//x的一次上升幂f(x)=x,零次项系数为0,一次项系数为1
	if(x == 1) { F.a.resize(2); F.a[1] = 1; return; }
	//递归,通过f(n)求出f(x)
	solve(x >> 1);
	int n = (x >> 1);
	//计算出A、B
	A.a.resize(n+1), B.a.resize(n+1);
	for(int i = 0; i <= n; i++) A.a[i] = F.a[i] * fac[i] % mod;
	for(int i = 0, pw = 1; i <= n; i++, pw = pw * n % mod) 
        B.a[i] = pw * fac_inv[i] % mod;
	reverse(B.a.begin(), B.a.begin() + n + 1);
	//A与B卷积,把第n+1~2n位向左平移,之后A的每项系数除以阶乘,F再卷上A
	A = A * B;
	for(int i = 0; i <= n; i++) A.a[i] = A.a[i + n];
	for(int i = 0; i <= n; i++) A.a[i] = A.a[i] * fac_inv[i] % mod;
	A.a.resize(n+1);
	F = A * F;
	//若x是奇数,则2*n=x-1,上升幂需要再卷上一个(x+2*n),左移,每个系数都乘上2*n
	if(x & 1) {
		F.a.resize(2 * n + 2);
		for(int i = 2 * n + 1; i >= 1; i--) 
            F.a[i] = (F.a[i - 1] + (x - 1) * F.a[i] % mod) % mod;
		F.a[0] = F.a[0] * (x - 1) % mod;
	}
}

TODO。

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇