zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    pip不是内部或外部命令也不是可运行的程序或批处理文件的问题
    动态规划 leetcode 343,279,91 & 639. Decode Ways,62,63,198
    动态规划 70.climbing Stairs ,120,64
    (双指针+链表) leetcode 19. Remove Nth Node from End of List,61. Rotate List,143. Reorder List,234. Palindrome Linked List
    建立链表的虚拟头结点 203 Remove Linked List Element,82,147,148,237
    链表 206 Reverse Linked List, 92,86, 328, 2, 445
    (数组,哈希表) 219.Contains Duplicate(2),217 Contain Duplicate, 220(3)
    重装系统
    java常用IO
    端口
  • 原文地址:https://www.cnblogs.com/ezoiLZH/p/9426055.html
Copyright © 2011-2022 走看看