斯特林数
斯特林数(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 }