斯特林数

斯特林数(Stirling number)

前置概念

组合数:$({{n}\atop{k}})$

上升幂:$x^{\overline{n}}=x(x+1)…(x+n-1)=\frac{(x+n-1)!}{(x-1)!}$

下降幂:$x^{\underline{n}}=x(x-1)…(x-n+1)=\frac{x!}{(x-n)!}=\frac{x!}{n!(x-n)!}n!=({{n}\atop{k}})n!$

自然数幂求和:$S_n (k)=\sum\limits_{i=0}^{n}i^k$

第一类斯特林数$[{{n}\atop{k}}]$

定义

将n个元素分成k个轮换的方案数即为$[{{n}\atop{k}}]$。(简单来说就是把n个元素围成k个圈)

递推式:$[{{n}\atop{k}}]=(n-1)[{{n-1}\atop{k}}]+[{{n-1}\atop{k-1}}]$

解释↑:新元素要么加入之前的轮换中,要么自成轮换。

性质

$x^{\overline{n}}=\sum\limits_{k=0}^{n}[{{n}\atop{k}}]x^k$

证明↑:

$x^{\overline{n}}=(x+n-1)x^{\overline{n-1}}$

$=(x+n-1)\sum\limits_{k=0}^{n-1}[{{n-1}\atop{k}}]x^k$

$=\sum\limits_{k=0}^{n-1}(x+n-1)[{{n-1}\atop{k}}]x^k$

$=\sum\limits_{k=0}^{n-1}(n-1)[{{n-1}\atop{k}}]x^k+[{{n-1}\atop{k}}]x^{k+1}$

$=(n-1)[{{n-1}\atop{0}}]x^0+[{{n-1}\atop{n-1}}]x^n+\sum\limits_{k=1}^{n-1}((n-1)[{{n-1}\atop{k}}]+[{{n-1}\atop{k-1}}])x^k$

$=[{{n}\atop{0}}]x^0+[{{n}\atop{n}}]x^n+\sum\limits_{k=1}^{n-1}[{{n}\atop{k}}]x^k$($(n-1)[{{n-1}\atop{0}}]=[{{n}\atop{0}}]=1,[{{n-1}\atop{n-1}}]=[{{n}\atop{n}}]=1$)

$=\sum\limits_{k=0}^{n}[{{n}\atop{k}}]x^k$

证毕。

由$x^{\underline{n}}=(-1)^n(-x)^{\overline{n}}$得$x^{\underline{n}}=\sum\limits_{k=0}^{n}(-1)^{n+k}[{{n}\atop{k}}]x^k$

带符号第一类斯特林数$S(n,k)=(-1)^{n+k}[{{n}\atop{k}}]$

求值

由$x^{\overline{n}}=\sum\limits_{k=0}^{n}[{{n}\atop{k}}]x^k$可知斯特林数为$x^{\overline{n}}$的各项系数。

我们可以直接分治FFT,时间复杂度$O(nlog{{2}\atop{2}}n)$。

然而有$O(nlog{{}\atop{2}}n)$的做法。

假设我们已经求出$x^{\overline{n}}=\sum\limits_{k=0}^{n}a{{}\atop{k}}x^k$,现在要求$x^{\overline{2n}}=x^{\overline{n}}(x+n)^{\overline{n}}$。

$(x+n)^{\overline{n}}=\sum\limits_{i=0}^{n}[{{n}\atop{i}}](x+n)^i$

$=\sum\limits_{i=0}^{n}a{{}\atop{i}}\sum\limits_{j=0}^{i}({{i}\atop{j}})x^{j}n^{i-j}$

1 代码还没打呢,打完了就贴上来qwq~

题目(还没做TAT~)

第二类斯特林数$\{{{n}\atop{k}}\}$

代码

调了一整天,打完之后变成一只废人了TAT~

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const ll mod=998244353;
 8 const int N=100000;
 9 int n,k,len,rev[(N<<2)+10]={0};
10 ll fac[N+10]={1},inv[N+10]={1};
11 ll a[(N<<2)+10],b[(N<<2)+10];
12 ll power(ll x,ll k){
13     ll ret=1,s=x;
14     for(ll i=1LL;i<=k;i<<=1){
15         if(k&i)
16             ret=ret*s%mod;
17         s=s*s%mod;
18     }
19     return ret;
20 }
21 void ntt(ll f[],int p){
22     for(int i=1;i<len;i++)
23         rev[i]=rev[i>>1]>>1|((i&1)?(len>>1):0);
24     for(int i=1;i<len;i++)
25         if(i<rev[i])
26             swap(f[i],f[rev[i]]);
27     for(int i=2;i<=len;i<<=1){
28         ll f1=power(3,(mod-1)/i);
29         for(int j=0;j<len;j+=i){
30             ll f2=1;
31             for(int k=j;k<j+(i>>1);k++){
32                 ll f3=f[k],f4=f2*f[k+(i>>1)]%mod;
33                 f[k]=(f3+f4)%mod;
34                 f[k+(i>>1)]=(f3-f4+mod)%mod;
35                 f2=f2*f1%mod;
36             }
37         }
38     }
39     if(!~p){
40         ll inv=power(len,mod-2);
41         for(int i=0;i<len;i++)
42             f[i]=f[i]*inv%mod;
43         reverse(f+1,f+len);
44     }
45     return;
46 }
47 int main(){
48     for(int i=1;i<=N;i++)
49         fac[i]=fac[i-1]*i%mod;
50     inv[N]=power(fac[N],mod-2);
51     for(int i=N-1;i;i--)
52         inv[i]=inv[i+1]*(i+1)%mod;
53     scanf("%d%d",&n,&k);
54     for(int i=0;i<=k;i++){
55         a[i]=inv[i]*(i&1?-1:1);
56         b[i]=power(i,n)*inv[i]%mod;
57     }
58     len=1;
59     while(len<((k+1)<<1))
60         len<<=1;
61     for(int i=k+1;i<len;i++)
62         a[i]=b[i]=0;
63     ntt(a,1);ntt(b,1);
64     for(int i=0;i<len;i++)
65         a[i]=a[i]*b[i]%mod;
66     ntt(a,-1);
67     for(int i=0;i<=n;i++)
68         printf("%lld ",a[i]);
69     puts("");
70     return 0;
71 }

 

posted @ 2018-08-04 20:48  乖巧的小团子QwQ  阅读(278)  评论(2编辑  收藏  举报