zoukankan      html  css  js  c++  java
  • 斯特林数

    斯特林数(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 }
  • 相关阅读:
    新建一个类并绑定一个activity
    关于fragment保存变量的问题
    关于使用别人方法的效率问题
    使用asynctask的问题
    关于整个头像更新问题(2)
    关于查找所需代码的问题
    静态变量的使用问题
    关于更换头像的整个过程理解
    fill_parent 和 match_parent区别
    关于ui修改的若干想法
  • 原文地址:https://www.cnblogs.com/gzez181027/p/Stirling_number.html
Copyright © 2011-2022 走看看