# Stirling数

### 第一类$$Stirling$$数

$$\begin{bmatrix} n \\ m \\ \end{bmatrix}$$表示$$n$$个元素组成$$m$$个圆排列的方案数。

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

$\begin{bmatrix} 0 \\ 0 \\ \end{bmatrix}=1, \begin{bmatrix} n \\ 0 \\ \end{bmatrix}=0(n>0)$

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

$n!=\sum_{i=0}^{n}\begin{bmatrix} n \\ i \\ \end{bmatrix}$

$\begin{bmatrix} n \\ 2 \\ \end{bmatrix}=(n-1)!\cdot \sum_{i=1}^{n-1}\frac{1}{i}$

$\begin{bmatrix} n \\ n-1 \\ \end{bmatrix}=\begin{pmatrix} n \\ 2 \\ \end{pmatrix}$

$\begin{bmatrix} n \\ n-2 \\ \end{bmatrix}=2\begin{pmatrix} n \\ 3 \\ \end{pmatrix}+3\begin{pmatrix} n \\ 4 \\ \end{pmatrix}$

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

$x^{\underline{n}}=\sum_{i=0}^{n}\begin{bmatrix} n \\ i \\ \end{bmatrix}(-1)^{n-i}x^i$

#### 求解第一类$$Stirling$$数

$\sum_{i=0}^{n}\begin{bmatrix} n \\ i \\ \end{bmatrix}x^i=\prod_{i=0}^{n-1}(x+i)$

$f_n=(x+n-1)f_{n-1}=xf_{n-1}+(n-1)f_{n-1}$

//by OIerC
//Forca Barcelona!
#include<cstdio>
#include<algorithm>
#define rep(i, a, b) for (register int i=(a); i<=(b); ++i)
#define per(i, a, b) for (register int i=(a); i>=(b); --i)
using namespace std;
const int N=400005, P=998244353, G=3;
inline int add(int x, int y){return x+y>=P?x+y-P:x+y;}
inline int sub(int x, int y){return x-y<0?x-y+P:x-y;}
inline int mul(int x, int y){return 1ll*x*y-1ll*x*y/P*P;}
int S[20][N], rev[N], n, A, B;

{
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}

int Pow(int x, int t)
{
int res=1;
for (; t; t>>=1, x=mul(x, x)) if (t&1) res=mul(res, x);
return res;
}

int C(int n, int m)
{
int ans=1;
rep(i, n-m+1, n) ans=mul(ans, i);
rep(i, 1, m) ans=mul(ans, Pow(i, P-2));
return ans;
}

void NTT(int *a, int n, int x)
{
for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i], a[rev[i]]);
for (int mid=1, len=2; mid<n; mid<<=1, len<<=1)
{
int Gn=Pow(G, (P-1)/len);
for (int i=0; i<n; i+=len)
{
int Gen=1;
for (int j=0; j<mid; j++, Gen=mul(Gen, Gn))
{
int A1=a[i+j], A2=mul(Gen, a[i+j+mid]);
}
}
}
if (!~x)
{
reverse(a+1, a+n);
int inv=Pow(n, P-2);
for (int i=0; i<n; i++) a[i]=mul(a[i], inv);
}
}

void solve(int l, int r, int deg)
{
if (l==r) {S[deg][0]=l; S[deg][1]=1; return;}
int mid=l+r>>1, lim=1, cnt=0;
while (lim<=r-l+1) lim<<=1, cnt++;
solve(l, mid, deg+1);
rep(i, 0, mid-l+1) S[deg][i]=S[deg+1][i];
solve(mid+1, r, deg+1);
rep(i, mid-l+2, lim) S[deg][i]=0;
rep(i, r-mid+1, lim) S[deg+1][i]=0;
rep(i, 0, lim-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
NTT(S[deg], lim, 1); NTT(S[deg+1], lim, 1);
rep(i, 0, lim-1) S[deg][i]=mul(S[deg][i], S[deg+1][i]);
NTT(S[deg], lim, -1);
}

int main()
{
if (n-1<A+B-2 || !A || !B) {puts("0"); return 0;}
else if (n==1) {puts("1"); return 0;}
solve(0, n-2, 0);
printf("%d\n", mul(C(A+B-2, A-1), S[0][A+B-2]));
return 0;
}



### 第二类$$Stirling$$数

$$\begin{Bmatrix} n \\ m \\ \end{Bmatrix}$$表示$$n$$个元素放入$$m$$个无差别盒子且每个盒子非空的方案数。

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

$\begin{Bmatrix} 0 \\ 0 \\ \end{Bmatrix}=1$

#### 性质

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

$n^{m}=\sum_{i=0}^{n} \begin{Bmatrix} m \\ i \\ \end{Bmatrix} * A_n^i$

\begin{align} \begin{Bmatrix} n \\ m \\ \end{Bmatrix}& = \frac{1}{m !} \sum_{i=0}^{m}(-1)^{i} \left( \begin{array}{c}{m} \\ {i}\end{array}\right)(m-i)^{n}\\ & = \sum_{i=0}^{n}\frac{(-1)^i(n-i)^n}{i!(m-i)!}\\ \end{align}

### 例题

$$HEOI2016/TJOI2016$$ 求和

\begin{align} f(n) &=\sum_{i=0}^{n}\sum_{j=0}^{i}\begin{Bmatrix} i \\ j \\ \end{Bmatrix}2^j\times j!\\ & =\sum_{j=0}^{n}2^j\times j!\sum_{i=0}^{n}\begin{Bmatrix} i \\ j \\ \end{Bmatrix}\\ & = \sum_{j=0}^{n}2^j\times j!\sum_{i=0}^{n}\sum_{k=0}^{j}\frac{(-1)^k(j-k)^i}{k!(i-k)!}\\ &=\sum_{j=0}^{n}2^j\times j!\sum_{k=0}^{j}\frac{(-1)^k}{k!}\frac{\sum_{i=0}^{n}(j-k)^i}{(i-k)!} \end{align}

$$a_i=\frac{(-1)^i}{i},b_i=\frac{\sum_{j=0}^{n}i^j}{i!}$$$$a_i$$直接求，等比数列求和求$$b_i$$

//by OIerC
//Forca Barcelona!
#include<cstdio>
#include<algorithm>
#define rep(i, a, b) for (register int i=(a); i<=(b); ++i)
#define per(i, a, b) for (register int i=(a); i>=(b); --i)
using namespace std;
typedef long long ll;
const int P=998244353, G=3, N=4000005;
inline int add(int x, int y){return x+y>=P?x+y-P:x+y;}
inline int sub(int x, int y){return x-y<0?x-y+P:x-y;}
inline int mul(int x, int y){return 1ll*x*y-1ll*x*y/P*P;}
int f[N], g[N], rev[N], fac[N], ifac[N];

{
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}

int Pow(int x, int t)
{
int res=1;
for (; t; t>>=1, x=mul(x, x)) if (t&1) res=mul(res, x);
return res;
}

void NTT(int *a, int n, int x)
{
for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i], a[rev[i]]);
for (int mid=1, len=2; mid<n; mid<<=1, len<<=1)
{
int Gn=Pow(G, (P-1)/len);
for (int i=0; i<n; i+=len)
{
int Gen=1;
for (int j=0; j<mid; j++, Gen=mul(Gen, Gn))
{
int A1=a[i+j], A2=mul(Gen, a[i+j+mid]);
}
}
}
if (!~x)
{
reverse(a+1, a+n);
int inv=Pow(n, P-2);
for (int i=0; i<n; i++) a[i]=mul(a[i], inv);
}
}

int main()
{
rep(i, 1, n) fac[i]=mul(fac[i-1], i);
ifac[n]=Pow(fac[n], P-2);
per(i, n-1, 0) ifac[i]=mul(ifac[i+1], i+1);
rep(i, 0, n)
{
g[i]=i==1?n+1:mul(mul(sub(Pow(i, n+1), 1), Pow(sub(i, 1), P-2)), ifac[i]);
}
int lim=1, cnt=0;
while (lim<=n<<1) lim<<=1, cnt++;
rep(i, 0, lim) rev[i]=(rev[i>>1]>>1) | ((i&1)<<(cnt-1));
NTT(f, lim, 1); NTT(g, lim, 1);
rep(i, 0, lim) f[i]=mul(f[i], g[i]);
NTT(f, lim, -1);
rep(i, 0, n)
printf("%d\n", ans);
return 0;
}


$$CF932E\ Team Work$$

\begin{align} Ans&=\sum_{i=1}^{n}\begin{pmatrix} n \\ i \\ \end{pmatrix}i^k \\ &=\sum_{i=0}^{n}\frac{n!}{(n-i)!}\sum_{j=0}^{k}\begin{Bmatrix} k \\ j \\ \end{Bmatrix}\frac{i!}{(i-j)!}\\ &=\sum_{i=0}^{n}\sum_{j=0}^{k}\begin{Bmatrix} k \\ j \\ \end{Bmatrix}\frac{n!}{(n-i)!(i-j)!}\\ &=\sum_{j=0}^{k}\begin{Bmatrix} k \\ j \\ \end{Bmatrix}\sum_{i=0}^{n}\begin{pmatrix} n-j \\ n-i \\ \end{pmatrix}\cdot \frac{n!}{(n-j)!}\\ &=\sum_{j=0}^{k}\begin{Bmatrix} k \\ j \\ \end{Bmatrix}\frac{n!}{(n-j)!}2^{n-j} \end{align}

//by OIerC
//Forca Barcelona!
#include<cstdio>
#include<algorithm>
#define rep(i, a, b) for (register int i=(a); i<=(b); ++i)
#define per(i, a, b) for (register int i=(a); i>=(b); --i)
using namespace std;
const int N=5005, P=1000000007;
inline int add(int x, int y){return x+y>=P?x+y-P:x+y;}
inline int sub(int x, int y){return x-y<0?x-y+P:x-y;}
inline int mul(int x, int y){return 1ll*x*y-1ll*x*y/P*P;}
int S[N][N];

{
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}

int Pow(int x, int t)
{
int res=1;
for (; t; t>>=1, x=mul(x, x)) if (t&1) res=mul(res, x);
return res;
}

int main()
{
rep(i, 1, k) rep(j, 1, k) S[i][j]=add(S[i-1][j-1], mul(S[i-1][j], j));
int bin=Pow(2, n), inv_2=Pow(2, P-2), down=1, ans=0;
rep(i, 0, min(n, k))
{
bin=mul(bin, inv_2); down=mul(down, n-i);
}
printf("%d\n", ans);
return 0;
}


$$CF961G\ Partitions$$

posted @ 2019-05-04 23:28  OIerC  阅读(342)  评论(0编辑  收藏  举报