• 【BZOJ4555】【TJOI2016】【HEOI2016】求和 (第二类斯特林数+NTT卷积)


    Description

    在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心。

    现在他想计算这样一个函数的值:

    $$f(n)=sum_{i=0}^nsum_{j=0}^i S(i,j) imes 2^j imes(j!)$$

    $S(i,j)$表示第二类斯特林数,递推公式为:
    $S(i,j)=j imes S(i-1,j)+S(i-1,j-1),1leq jleq i-1$。
    边界条件为:$S(i,i)=1(0leq i),S(i,0)=0(1leq i)$
    你能帮帮他吗?

    Input

    输入只有一个正整数$n$

    Output

    输出$f(n)$。

    由于结果会很大,输出$f(n)$对$998244353(7×17×223+1)$取模的结果即可。

    题解:

    递推式给你就是玩你的,一点关系都没有!

    第二类斯特林数通项公式:

    $$S(i,j)=frac{1}{j!}sum_{k=0}^j(-1)^k C_j^k(j-k)^i$$

    代入原式得

    $$sum_{i=0}^nsum_{j=0}^i frac{1}{j!}sum_{k=0}^j(-1)^k C_j^k(j-k)^i imes 2^j imes(j!)$$

    组合数展开得

    $$sum_{i=0}^nsum_{j=0}^i 2^jsum_{k=0}^j(-1)^kfrac{j!}{k!(j-k)!}(j-k)^i$$

    交换枚举顺序得

    $$sum_{j=0}^n(j!)2^jsum_{k=0}^n{(-1)^kover k!}{1over (j-k)!}sum_{i=0}^n(j-k)^i$$

    看到又有$k$又有$j-k$,这不是卷积吗?

    令 $a(x)=sum_{x=0}^n{(-1)^xover x!}$

        $b(x)={1over (x)!}sum_{i=0}^n(x)^i$

    则 $f(x)=(x!)2^xsum_{i=0}^n a(x)b(x-i)$

    不过循环边界到n不会越界吗?这对答案没有影响,因为斯特林数和组合数都为0。

    那就直接NTT了,刚好给了一个NTT模数。(这莫非是提示?)

    CODE:

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 
     5 #define mod 998244353
     6 int n,bit=1,rev[400005],ans=0;
     7 long long fac[100005],inv[100005],ivf[100005];
     8 long long a[400005],b[400005];
     9 
    10 int qpow(int x,int y){
    11     int ans=1;
    12     while(y){
    13         if(y&1)ans=1LL*ans*x%mod;
    14         y>>=1,x=1LL*x*x%mod;
    15     }
    16     return ans;
    17 }
    18 
    19 void init(){
    20     fac[0]=ivf[0]=inv[0]=inv[1]=1;
    21     for(int i=1;i<=n;i++)fac[i]=fac[i-1]*i%mod;
    22     for(int i=2;i<=n;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    23     for(int i=1;i<=n;i++)ivf[i]=ivf[i-1]*inv[i]%mod;
    24     a[0]=b[0]=1;
    25     for(int i=1,f=-1;i<=n;i++,f=-f){
    26         if (i==1)a[i]=n+1;
    27         else a[i]=ivf[i]*(qpow(i,n+1)-1)%mod*inv[i-1]%mod;
    28         b[i]=f*ivf[i]%mod;
    29         if(a[i]<0)a[i]+=mod;
    30         if(b[i]<0)b[i]+=mod;
    31     }
    32 }
    33 
    34 void get_rev(){
    35     while(bit<=n+n)bit<<=1;
    36     for(int i=0;i<bit;i++)
    37     rev[i]=(rev[i>>1]>>1)|(i&1)*(bit>>1);
    38 }
    39 
    40 void NTT(long long a[],int dft){
    41     for(int i=0;i<bit;i++)
    42         if(i<rev[i])swap(a[i],a[rev[i]]);
    43     for(int i=1;i<bit;i<<=1){
    44         long long W=qpow(3,(mod-1)/i/2);
    45         if(dft==-1)W=qpow(W,mod-2);
    46         for(int j=0;j<bit;j+=i<<1){
    47             long long w=1;
    48             for(int k=j;k<i+j;k++,w=w*W%mod){
    49                 long long x=a[k];
    50                 long long y=w*a[k+i]%mod;
    51                 a[k]=(x+y)%mod,a[k+i]=(x+mod-y)%mod;
    52             }
    53         }
    54     }
    55     int inv=qpow(bit,mod-2);
    56     if(dft==-1)for(int i=0;i<bit;i++)a[i]=a[i]*inv%mod;
    57 }
    58 
    59 int main(){
    60     scanf("%d",&n);
    61     init();
    62     get_rev();
    63     NTT(a,1),NTT(b,1);
    64     for(int i=0;i<bit;i++)(a[i]*=b[i])%=mod;
    65     NTT(a,-1);
    66     for(int i=0;i<=n;i++){
    67         ans+=qpow(2,i)*fac[i]%mod*a[i]%mod;
    68         if(ans>=mod)ans-=mod;
    69     }
    70     printf("%d",ans);
    71 }
  • 相关阅读:
    Java多线程运行机制的基本原理
    JAVA IO中的设计模式
    C++ 内存泄露处理方法 (转)
    使用PageHeap.EXE或GFlags.EXE检查内存越界错误 (转)
    32位Windows7上8G内存使用感受+xp 32位下使用8G内存 (转)
    windows 32位系统中进程最大可用内存空间为3GB (转)
    OpenGL 4.0 GLSL 实现 投影纹理映射(Projective Texture Mapping) (转)
    DebugView 调试工具
    剑桥中国史:“571”——林彪的未遂政变(转)
    邱会作与儿子对话:林彪的莫须有之罪(转)
  • 原文地址:https://www.cnblogs.com/ezoiLZH/p/9426055.html
Copyright © 2020-2023  润新知