zoukankan      html  css  js  c++  java
  • Tjoi2016&Heoi2016 求和

    传送门

    我知道这题可以直接把第二类斯特林数展开后一遍NTT算出来(你们没看到我写的那篇博客么……),我只是想练一练分治NTT……

    题目要求的是

    egin{equation}Ans=sum_{i=0}^nsum_{j=0}^i S(i,j)×2^j×(j!)end{equation}

    egin{equation}A_i=sum_{j=0}^i S(i,j)×2^j×(j!)end{equation}

    那么$A_i$的实际意义就是把n个小球放入任意多个不同盒子,每个盒子还有两种状态(你可以认为盒子有红色和蓝色两种)的方案数。

    然后就不难写出$A_i$的递推式了:

    egin{equation}A_i=2sum_{j=0}^i C_i^j A_jend{equation}

    显然这个递推式是可以直接分治NTT的,那么分治NTT裸上就好了,复杂度$O(nlog^2 n)$。

     1 /**************************************************************
     2     Problem: 4555
     3     User: hzoier
     4     Language: C++
     5     Result: Accepted
     6     Time:3020 ms
     7     Memory:3892 kb
     8 ****************************************************************/
     9 #include<cstdio>
    10 #include<cstring>
    11 #include<algorithm>
    12 using namespace std;
    13 const int maxn=262200,p=998244353,g=3;
    14 void NTT(int*,int,int);
    15 int qpow(int,int,int);
    16 int n,N=1,f[maxn],A[maxn],B[maxn],ans=0;
    17 int main(){
    18     scanf("%d",&n);
    19     while(N<=(n<<1))N<<=1;
    20     f[0]=1;
    21     for(int i=1;i<=n;i++)f[i]=(long long)f[i-1]*i%p;
    22     for(int i=0;i<=n;i++){
    23         A[i]=qpow(f[i],p-2,p);
    24         B[i]=A[i];
    25         if(i&1)A[i]=(p-A[i])%p;
    26         if(i==1)B[i]=(long long)B[i]*(n+1)%p;
    27         else B[i]=(long long)B[i]*((qpow(i,n+1,p)-1+p)%p)%p*qpow((i-1+p)%p,p-2,p)%p;
    28     }
    29     NTT(A,N,1);
    30     NTT(B,N,1);
    31     for(int i=0;i<N;i++)A[i]=(long long)A[i]*B[i]%p;
    32     NTT(A,N,-1);
    33     for(int i=0,pw=1;i<=n;i++,pw=(pw<<1)%p)ans=(ans+(long long)pw*f[i]%p*A[i]%p)%p;
    34     printf("%d",ans);
    35     return 0;
    36 }
    37 void NTT(int *A,int n,int tp){
    38     for(int i=1,j=0,k;i<n-1;i++){
    39         k=n;
    40         do j^=(k>>=1);while(j<k);
    41         if(i<j)swap(A[i],A[j]);
    42     }
    43     for(int k=2;k<=n;k<<=1){
    44         int wn=qpow(g,(tp>0?(p-1)/k:(p-1)/k*(long long)(p-2)%(p-1)),p);
    45         for(int i=0;i<n;i+=k){
    46             int w=1;
    47             for(int j=0;j<(k>>1);j++,w=(long long)w*wn%p){
    48                 int a=A[i+j],b=(long long)w*A[i+j+(k>>1)]%p;
    49                 A[i+j]=(a+b)%p;
    50                 A[i+j+(k>>1)]=(a-b+p)%p;
    51             }
    52         }
    53     }
    54     if(tp<0){
    55         int inv=qpow(n,p-2,p);
    56         for(int i=0;i<n;i++)A[i]=(long long)A[i]*inv%p;
    57     }
    58 }
    59 int qpow(int a,int b,int p){
    60     int ans=1;
    61     for(;b;b>>=1,a=(long long)a*a%p)if(b&1)ans=(long long)ans*a%p;
    62     return ans;
    63 }
    View Code
  • 相关阅读:

    今天的收获080716
    手机写博客
    修改加速软件之本地分流(突破电信上网限制)
    Linux并不是传说中的那么不变
    Ubuntu Linux下的几款“磁盘操作阐明器”对比
    在SuSE中设置开机主动启动挨次
    Fedora显卡驱动的装配
    新Qt主题引擎让GNOME下KDE程序更舒服
    Ubuntu的运用总结
  • 原文地址:https://www.cnblogs.com/hzoier/p/6547422.html
Copyright © 2011-2022 走看看