斯特林数
(一)第一类斯特林数
s1(n,m)s1(n,m)s1(n,m)表示n个元素排成m个圆排列的个数,记作[nm]n \brack m[mn]
a.递推公式与性质
[nm]=[n−1m−1]+[n−1m]∗(n−1){n\brack m}={n-1\brack m-1}+{n-1\brack m}*(n-1)[mn]=[m−1n−1]+[mn−1]∗(n−1)
新来的元素既可以自己成为一个圆排列,又可以放在任意一个已有元素的后面。
b.和乘方&下降幂的关系、和乘方&上升幂的关系
nk‾=∑i=0k[ki]∗(−1)k−i∗nin^{\underline k}=\sum^k_{i=0}{k\brack i}*(-1)^{k-i}*n^ink=∑i=0k[ik]∗(−1)k−i∗ni
KaTeX parse error: Got function '\overline' with no arguments as superscript at position 3: n^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲k=\sum^k_{i=0}{…
证明1:(数学归纳法)
当k=0时显然成立,当k>0时
KaTeX parse error: Got function '\underline' with no arguments as superscript at position 3: n^\̲u̲n̲d̲e̲r̲l̲i̲n̲e̲ ̲k=(n-k+1)*n^\un…
=(n−k+1)∗∑i=0k−1[k−1i]∗(−1)k−1−i∗ni=(n-k+1)*\sum^{k-1}_{i=0}{k-1\brack i}*(-1)^{k-1-i}*n^i=(n−k+1)∗∑i=0k−1[ik−1]∗(−1)k−1−i∗ni
=n∗∑i=0k−1[k−1i]∗(−1)k−1−i∗ni−(k−1)∗∑i=0k−1[k−1i]∗(−1)k−1−i∗ni=n*\sum^{k-1}_{i=0}{k-1\brack i}*(-1)^{k-1-i}*n^i-(k-1)*\sum^{k-1}_{i=0}{k-1\brack i}*(-1)^{k-1-i}*n^i=n∗∑i=0k−1[ik−1]∗(−1)k−1−i∗ni−(k−1)∗∑i=0k−1[ik−1]∗(−1)k−1−i∗ni
=n∗∑i=1k[k−1i−1]∗(−1)k−i∗ni−1−(k−1)∗∑i=0k−1[k−1i]∗(−1)k−1−i∗ni=n*\sum^{k}_{i=1}{k-1\brack i-1}*(-1)^{k-i}*n^{i-1}-(k-1)*\sum^{k-1}_{i=0}{k-1\brack i}*(-1)^{k-1-i}*n^i=n∗∑i=1k[i−1k−1]∗(−1)k−i∗ni−1−(k−1)∗∑i=0k−1[ik−1]∗(−1)k−1−i∗ni
=∑i=1k[k−1i−1]∗(−1)k−i∗ni−∑i=1k(k−1)∗[k−1i]∗(−1)k−1−i∗ni=\sum^{k}_{i=1}{k-1\brack i-1}*(-1)^{k-i}*n^i-\sum^{k}_{i=1}(k-1)*{k-1\brack i}*(-1)^{k-1-i}*n^i=∑i=1k[i−1k−1]∗(−1)k−i∗ni−∑i=1k(k−1)∗[ik−1]∗(−1)k−1−i∗ni //注意i=0时若k=1则k−1=0k-1=0k−1=0,否则[k−1i]=0{k-1\brack i}=0[ik−1]=0;i=k时[k−1i]=0{k-1\brack i}=0[ik−1]=0
=∑i=1k[k−1i−1]∗(−1)k−i∗ni+∑i=1k(k−1)∗[k−1i]∗(−1)k−i∗ni=\sum^{k}_{i=1}{k-1\brack i-1}*(-1)^{k-i}*n^i+\sum^{k}_{i=1}(k-1)*{k-1\brack i}*(-1)^{k-i}*n^i=∑i=1k[i−1k−1]∗(−1)k−i∗ni+∑i=1k(k−1)∗[ik−1]∗(−1)k−i∗ni
=∑i=1k([k−1i−1]+(k−1)∗[k−1i])∗(−1)k−i∗ni=\sum^{k}_{i=1}({k-1\brack i-1}+(k-1)*{k-1\brack i})*(-1)^{k-i}*n^i=∑i=1k([i−1k−1]+(k−1)∗[ik−1])∗(−1)k−i∗ni
=∑i=0k[ki]∗(−1)k−i∗ni=\sum^k_{i=0}{k\brack i}*(-1)^{k-i}*n^i=∑i=0k[ik]∗(−1)k−i∗ni
证明2:(数学归纳法)(类似的就不写那么详细了)
当k=0时显然成立,当k>0时
KaTeX parse error: Got function '\overline' with no arguments as superscript at position 3: n^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲k=(n+k-1)*n^\ov…
=(n+k−1)∗∑i=0k−1[k−1i]∗ni=(n+k-1)*\sum^{k-1}_{i=0}{k-1\brack i}*n^i=(n+k−1)∗∑i=0k−1[ik−1]∗ni
=∑i=1k∗[k−1i−1]∗ni+∑i=1k[k−1i]∗(k−1)∗ni=\sum^k_{i=1}*{k-1\brack i-1}*n^i+\sum^{k}_{i=1}{k-1\brack i}*(k-1)*n^i=∑i=1k∗[i−1k−1]∗ni+∑i=1k[ik−1]∗(k−1)∗ni
=∑i=0k[ki]∗ni=\sum^k_{i=0}{k\brack i}*n^i=∑i=0k[ik]∗ni
现实意义:将下降幂用n^i展开,其系数绝对值为第一类斯特林数,且正负性交错,而将上升幂展开,其系数即为第一类斯特林数
c.求第n行的第一类斯特林数
为了方便用上升幂的柿子来求。柿子本来是这样的KaTeX parse error: Got function '\overline' with no arguments as superscript at position 3: n^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲k=\prod^{n+k-1}…,但因为要算第n行,变成这样KaTeX parse error: Got function '\overline' with no arguments as superscript at position 3: x^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲n=\prod^{n-1}_{…,其中x是一个未知数
注意到上升幂展开,其系数即为第一类斯特林数,换言之就是要把第二个柿子的每个数看成一个多项式乘起来,最后的系数就是答案。nice可以做到O(n2logn)O(n^2logn)O(n2logn)啦。下面就不用看了
用脑子考虑分治,多项式初始长度为2,合并一次长度翻倍
T(n)=2T(n2)+O(nlogn)T(n)=2T({n\over 2})+O(nlogn)T(n)=2T(2n)+O(nlogn) 所以时间复杂度为O(nlog2n)O(nlog^2n)O(nlog2n)
进一步优化
因为KaTeX parse error: Got function '\overline' with no arguments as superscript at position 3: x^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲{2n}=(\prod^{n-…,如果能够通过∏i=0n−1x+i\prod^{n-1}_{i=0}x+i∏i=0n−1x+i得到∏i=0n−1x+n+i\prod^{n-1}_{i=0}x+n+i∏i=0n−1x+n+i(这东西=KaTeX parse error: Got function '\overline' with no arguments as superscript at position 8: =(x+n)^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲n),则T(n)=T(n2)+O(nlogn)T(n)=T({n\over 2})+O(nlogn)T(n)=T(2n)+O(nlogn) 时间复杂度O(nlogn)O(nlogn)O(nlogn)
我们设前者得到的多项式f(x)=∑i=0L−1ai∗xif(x)=\sum^{L-1}_{i=0} ai*x^if(x)=∑i=0L−1ai∗xi,则多项式f(x+n)=∑i=0L−1ai∗(x+n)if(x+n)=\sum^{L-1}_{i=0} ai*(x+n)^if(x+n)=∑i=0L−1ai∗(x+n)i即为所求
f(x+n)=∑i=0L−1ai∗(x+n)i=∑i=0L−1ai∗∑j=0i(ij)∗ni−j∗xjf(x+n)=\sum^{L-1}_{i=0} a_i*(x+n)^i=\sum^{L-1}_{i=0} a_i*\sum^i_{j=0}{i\choose j}*n^{i-j}*x^jf(x+n)=∑i=0L−1ai∗(x+n)i=∑i=0L−1ai∗∑j=0i(ji)∗ni−j∗xj //二项式展开
=∑i=0L−1(∑j=iL−1(ji)∗nj−i∗aj)∗xi=\sum^{L-1}_{i=0}(\sum^{L-1}_{j=i}{j\choose i}*n^{j-i}*a_j)*x^i=∑i=0L−1(∑j=iL−1(ij)∗nj−i∗aj)∗xi
问题在如何处理出ci=∑j=iL−1(ji)∗nj−i∗ajc_i=\sum^{L-1}_{j=i}{j\choose i}*n^{j-i}*a_jci=∑j=iL−1(ij)∗nj−i∗aj
=1i!∑j=iL−1j!(j−i)!∗nj−i∗aj={1\over i!}\sum^{L-1}_{j=i}{j!\over (j-i)!}*n^{j-i}*a_j=i!1∑j=iL−1(j−i)!j!∗nj−i∗aj
令g(j)=j!∗aj,h(j)=njj!且当j≤0时=0g(j)=j!*a_j,h(j)={n^{j}\over j!}且当j\leq0时=0g(j)=j!∗aj,h(j)=j!nj且当j≤0时=0
=1i!∑j=0L−1g(j)∗h(j−i)={1\over i!}\sum^{L-1}_{j=0}g(j)*h(j-i)=i!1∑j=0L−1g(j)∗h(j−i)
事实上这已经是一个经典问题了,但是我忘了,所以再推一遍:
不希望h的定义域有负数,人为向右移L位:=1i!∑j=0L−1g(j)∗h(j−i+L)={1\over i!}\sum^{L-1}_{j=0}g(j)*h(j-i+L)=i!1∑j=0L−1g(j)∗h(j−i+L)
把总长为2L的h反过来:=1i!∑j=0L−1g(j)∗h(i−j+L−1)={1\over i!}\sum^{L-1}_{j=0}g(j)*h(i-j+L-1)=i!1∑j=0L−1g(j)∗h(i−j+L−1)
就这样卷积完以后,再左移L-1位就可以了
总的实现思路:
1:递归求解KaTeX parse error: Got function '\overline' with no arguments as superscript at position 3: x^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲{\lfloor{n\over…的多项式
2:通过KaTeX parse error: Got function '\overline' with no arguments as superscript at position 3: x^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲{\lfloor{n\over…的多项式得到KaTeX parse error: Got function '\overline' with no arguments as superscript at position 16: (x+{n\over 2})^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲{\lfloor{n\over…的多项式
3:两式相乘得到KaTeX parse error: Got function '\overline' with no arguments as superscript at position 3: x^\̲o̲v̲e̲r̲l̲i̲n̲e̲{\lfloor{n\over…
4:若n为奇数,再乘上x+n
我的代码遇上卡常的基本过不去
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int _=1e2;
const int maxn=(1<<18)+_;
const int mod=167772161;
inline int ad(int x,int y){return x>=mod-y?x-mod+y:x+y;}
inline int re(int x,int y){return x<y?x-y+mod:x-y;}
inline int mu(int x,int y){return (LL)x*y%mod;}
inline int qp(int x,int y){int r=1;while(y){if(y&1)r=mu(r,x);x=mu(x,x),y>>=1;}return r;}
inline int dv(int x,int y){return mu(x,qp(y,mod-2));}
int fac[2*maxn],fac_inv[2*maxn];
void yu()
{
fac[0]=1;
for(int i=1;i<2*maxn;i++)fac[i]=mu(i,fac[i-1]);
fac_inv[2*maxn-1]=qp(fac[2*maxn-1],mod-2);
for(int i=2*maxn-2;i>=0;i--)fac_inv[i]=mu(fac_inv[i+1],i+1);
}
namespace J
{
int Re[4*maxn];
void NTT(int *a,int n,int op)
{
for(int i=0;i<n;i++)
if(i<Re[i])swap(a[i],a[Re[i]]);
for(int i=1;i<n;i<<=1)
{
int gn=qp(3,(mod-1)/(i<<1));
if(op==-1)gn=qp(gn,mod-2);
for(int j=0;j<n;j+=(i<<1))
{
int g=1;
for(int k=0;k<i;k++,g=mu(g,gn))
{
int k1=a[j+k],k2=mu(a[j+k+i],g);
a[j+k]=ad(k1,k2);
a[j+k+i]=re(k1,k2);
}
}
}
if(op==-1)
{
int inv=qp(n,mod-2);
for(int i=0;i<n;i++)a[i]=mu(a[i],inv);
}
}
int n,m,L,A[4*maxn],B[4*maxn];
void main()
{
int tn=n,tm=m;
m=n+m-1;for(n=1,L=0;n<=m;n<<=1)L++;
for(int i=0;i<n;i++)Re[i]=(Re[i>>1]>>1)|((i&1)<<(L-1));
for(int i=tn;i<n;i++)A[i]=0;
for(int i=tm;i<n;i++)B[i]=0;
NTT(A,n,1),NTT(B,n,1);
for(int i=0;i<n;i++)A[i]=mu(A[i],B[i]);
NTT(A,n,-1);
}
}using namespace J;
int len,a[2*maxn],b[4*maxn];
void solve(int n)
{
if(n==1){len=2,a[1]=1;return ;}
solve(n/2);
J::n=len,J::m=2*len;
for(int i=0,t=1;i<len;i++,t=mu(t,n/2))
A[i]=mu(fac[i],a[i]),B[i]=0,B[i+len]=mu(t,fac_inv[i]);
reverse(B,B+2*len);
J::main();
for(int i=0;i<len;i++)b[i]=mu(A[i+len-1],fac_inv[i]);
J::n=len,J::m=len;
for(int i=0;i<len;i++)
A[i]=a[i],B[i]=b[i];
J::main();
len=J::m;
for(int i=0;i<len;i++)a[i]=A[i];
if(n&1)
{
for(int i=0;i<len;i++)b[i]=mu(a[i],n-1); b[len+1]=0;
for(int i=len;i>=1;i--)a[i]=a[i-1]; a[0]=0;
len++;
for(int i=0;i<len;i++)a[i]=ad(a[i],b[i]);
}
}
int main()
{
int n;
scanf("%d",&n); yu();
solve(n);
for(int i=0;i<=n;i++)printf("%d ",a[i]);
return 0;
}
(二)第二类斯特林数
s2(n,m)s2(n,m)s2(n,m)表示n个元素划分到m个集合的方案数,记作{nm}n\brace m{mn}
a.递推公式与性质
{nm}={n−1m−1}+{n−1m}∗m{n\brace m}={n-1\brace m-1}+{n-1\brace m}*m{mn}={m−1n−1}+{mn−1}∗m
新来的元素可以自己成为一个集合,或者放到任意一个已有集合里
b.和乘方&下降幂的关系、和乘方&上升幂的关系
KaTeX parse error: Got function '\underline' with no arguments as superscript at position 31: …}{k\brace i}*n^\̲u̲n̲d̲e̲r̲l̲i̲n̲e̲ ̲i 也可写作nk=∑i=0m{ki}∗i!∗(ni)n^k=\sum^m_{i=0}{k\brace i}*i!*{n\choose i}nk=∑i=0m{ik}∗i!∗(in)
KaTeX parse error: Got function '\overline' with no arguments as superscript at position 42: …}*(-1)^{k-i}*n^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲i
证明1:(数学归纳法)
当k=0时显然成立,当k>0时
nkn^knk=n(k−1)∗nn^{(k-1)}*nn(k−1)∗n
KaTeX parse error: Got function '\underline' with no arguments as superscript at position 36: …k-1\brace i}*n^\̲u̲n̲d̲e̲r̲l̲i̲n̲e̲ ̲i*(n-i+i)
KaTeX parse error: Got function '\underline' with no arguments as superscript at position 37: …-1\brace i}*(n^\̲u̲n̲d̲e̲r̲l̲i̲n̲e̲ ̲{i+1}+i*n^\unde…
KaTeX parse error: Got function '\underline' with no arguments as superscript at position 36: …k-1\brace i}*n^\̲u̲n̲d̲e̲r̲l̲i̲n̲e̲ ̲{i+1}+\sum^{(k-…
KaTeX parse error: Got function '\underline' with no arguments as superscript at position 34: …1\brace i-1}*n^\̲u̲n̲d̲e̲r̲l̲i̲n̲e̲ ̲i+\sum^{k}_{i=1… //注意i=0时i=0i=0i=0,i=k时{k−1i}=0{k-1\brace i}=0{ik−1}=0
KaTeX parse error: Got function '\underline' with no arguments as superscript at position 18: …sum^{k}_{i=1}n^\̲u̲n̲d̲e̲r̲l̲i̲n̲e̲ ̲i*({k-1\brace i…
KaTeX parse error: Got function '\underline' with no arguments as superscript at position 18: …sum^{k}_{i=0}n^\̲u̲n̲d̲e̲r̲l̲i̲n̲e̲ ̲i*{k\brace i} //注意i=0且k>0时{ki}=0{k\brace i}=0{ik}=0
从组合意义理解nk=∑i=0n{ki}∗i!∗(ni)n^k=\sum^n_{i=0}{k\brace i}*i!*{n\choose i}nk=∑i=0n{ik}∗i!∗(in)
左边:k个球放进n个有序盒子,随便放
右边:选i个盒子出来放,把盒子当集合把球划分,实际上盒子有序,再乘i!
证明2:(数学归纳法)(同样类似)
当k=0时显然成立,当k>0时
nkn^knk=n(k−1)∗nn^{(k-1)}*nn(k−1)∗n
KaTeX parse error: Got function '\overline' with no arguments as superscript at position 49: …(-1)^{k-1-i}*n^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲i*(n+i-i)
KaTeX parse error: Got function '\overline' with no arguments as superscript at position 45: …}*(-1)^{k-i}*n^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲i-\sum^{k}_{i=1…
KaTeX parse error: Got function '\overline' with no arguments as superscript at position 39: …}*(-1)^{k-i}*n^\̲o̲v̲e̲r̲l̲i̲n̲e̲ ̲i
c.求第n行的第二类斯特林数
{nm}=1m!∑i=0m(−1)(m−i)∗(mi)∗mn{n\brace m}={1\over m!}\sum^m_{i=0}(-1)^{(m-i)}*{m\choose i}*m^n{mn}=m!1∑i=0m(−1)(m−i)∗(im)∗mn n是常数,(−1)(m−i)(-1)^{(m-i)}(−1)(m−i)和(mi){m\choose i}(im)分别弄一个多项式然后FFT卷起来即可
证明(利用广义容斥原理)
令f(m)={nm}∗m!f(m)={n\brace m}*m!f(m)={mn}∗m! 意为把n个球放恰好m个有序盒子的方案数
令g(m)=mng(m)=m^ng(m)=mn 意为把n个球放至多m个有序盒子中
则g(m)=∑i=0mh(i)f(i)g(m)=\sum^m_{i=0} h(i)f(i)g(m)=∑i=0mh(i)f(i),考虑容斥系数,对于计算g(j)时f(i)对g(j)的贡献次数,i个盒子可以按顺序放在总共j个位置中的不同位置,即组合数,哦,原来是二项式反演啊
则g(m)=∑i=0m(mi)f(i)g(m)=\sum^m_{i=0} {m \choose i}f(i)g(m)=∑i=0m(im)f(i)
则f(m)=∑i=0m(−1)(m−i)∗(mi)∗g(i)f(m)=\sum^m_{i=0}(-1)^{(m-i)}*{m\choose i}*g(i)f(m)=∑i=0m(−1)(m−i)∗(im)∗g(i)
即{nm}∗m!=∑i=0m(−1)(m−i)∗{mi}∗mn{n\brace m}*m!=\sum^m_{i=0}(-1)^{(m-i)}*{m\brace i}*m^n{mn}∗m!=∑i=0m(−1)(m−i)∗{im}∗mn