码迷,mamicode.com
首页 > 其他好文 > 详细

斯特林数的计算方法

时间:2020-07-01 09:38:51      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:pac   one   str   open   size   clu   while   def   alt   

  做了一个斯特林数的题,发现需要快速求第一类斯特林数,感觉是时候学一下了。按照从简单到难的顺序来写吧。

 

第二类斯特林数·行

  给出n,求$\begin{Bmatrix} n\\0 \end{Bmatrix}~,~\begin{Bmatrix} n\\1 \end{Bmatrix}\dots\begin{Bmatrix} n\\n \end{Bmatrix}$;$n\leq 2\times 10^5$

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

  $=\frac{1}{m!}\sum\limits_{i=0}^m(-1)^i\frac{m!}{i!(m-i)!}(m-i)^n$

  $=\sum\limits_{i=0}^m\frac{(-1)^i(m-i)^n}{i!(m-i)!}$

  $=\sum\limits_{i=0}^m\frac{(-1)^i}{i!}\times \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 }
第二类斯特林数·行

 

 

第一类斯特林数·行

 

第二类斯特林数·列

 

第一类斯特林数·列

斯特林数的计算方法

标签:pac   one   str   open   size   clu   while   def   alt   

原文地址:https://www.cnblogs.com/shzr/p/13217263.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!