斯特林数的计算方法
Posted shzr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了斯特林数的计算方法相关的知识,希望对你有一定的参考价值。
做了一个斯特林数的题,发现需要快速求第一类斯特林数,感觉是时候学一下了。按照从简单到难的顺序来写吧。
第二类斯特林数·行
给出n,求$egin{Bmatrix} n\0 end{Bmatrix}~,~egin{Bmatrix} n\1 end{Bmatrix}dotsegin{Bmatrix} n\n end{Bmatrix}$;$nleq 2 imes 10^5$
$egin{Bmatrix} n\m end{Bmatrix}=frac{1}{m!}sumlimits_{i=0}^m(-1)^iinom{m}{i}(m-i)^n$
$=frac{1}{m!}sumlimits_{i=0}^m(-1)^ifrac{m!}{i!(m-i)!}(m-i)^n$
$=sumlimits_{i=0}^mfrac{(-1)^i(m-i)^n}{i!(m-i)!}$
$=sumlimits_{i=0}^mfrac{(-1)^i}{i!} imes frac{(m-i)^n}{(m-i)!}$
可以看得出,由于 (m-i)+i=m ,这就是一个卷积的形式了。我们把:$f(x)=sum frac{(-1)^i}{i!}x^i$ 和 $g(x)=sum frac{x^n}{x!}x^i$ 卷起来,得到的多项式的各项系数就是答案啦。
1 # include <cstdio> 2 # include <iostream> 3 # define R register int 4 5 using namespace std; 6 7 const int N=600005; 8 const int mod=167772161; 9 const int inv_g=(mod+1)/3; 10 int n,f[N],g[N],len,rev[N]; 11 int inv[N],fac[N]; 12 13 int add (int a,int b) 14 { 15 a+=b; 16 if(a>=mod) return a-mod; 17 return a; 18 } 19 20 int dec (int a,int b) 21 { 22 a-=b; 23 if(a<0) return a+mod; 24 return a; 25 } 26 27 int qui (int a,int b) 28 { 29 int s=1; 30 while(b) 31 { 32 if(b&1) s=1LL*s*a%mod; 33 a=1LL*a*a%mod; 34 b>>=1; 35 } 36 return s; 37 } 38 39 void NTT (int *f,int v) 40 { 41 for (R i=1;i<=len;++i) 42 if(i<rev[i]) swap(f[i],f[ rev[i] ]); 43 for (R i=2;i<=len;i<<=1) 44 { 45 int ln=i/2,og1=qui((v==1)?3:inv_g,(mod-1)/i); 46 for (R b=0;b<len;b+=i) 47 { 48 int og=1; 49 for (R x=b;x<b+ln;++x) 50 { 51 int t=1LL*og*f[x+ln]%mod; 52 f[x+ln]=dec(f[x],t); 53 f[x]=add(f[x],t); 54 og=1LL*og*og1%mod; 55 } 56 } 57 } 58 if(v==1) return ; 59 int inv=qui(len,mod-2); 60 for (R i=0;i<=len;++i) f[i]=1LL*f[i]*inv%mod; 61 } 62 63 int main() 64 { 65 scanf("%d",&n); 66 fac[0]=1; for (R i=1;i<=n;++i) fac[i]=1LL*i*fac[i-1]%mod; 67 inv[n]=qui(fac[n],mod-2); 68 for (R i=n;i>=1;--i) inv[i-1]=1LL*inv[i]*i%mod; 69 len=1; while(len<=2*(n+1)) len<<=1; 70 for (R i=0;i<=n;++i) 71 { 72 if(i&1) f[i]=mod-inv[i]; else f[i]=inv[i]; 73 g[i]=1LL*qui(i,n)*inv[i]%mod; 74 } 75 for (R i=1;i<=len;++i) rev[i]=(rev[i>>1]>>1)|((i&1)?(len>>1):0); 76 NTT(f,1); NTT(g,1); 77 for (R i=0;i<=len;++i) f[i]=1LL*f[i]*g[i]%mod; 78 NTT(f,-1); 79 for (R i=0;i<=n;++i) printf("%d ",f[i]); 80 return 0; 81 }
第一类斯特林数·行
第二类斯特林数·列
第一类斯特林数·列
以上是关于斯特林数的计算方法的主要内容,如果未能解决你的问题,请参考以下文章