求和:fft,表达式化简

$f(n)=\sum\limits_{i=0}^{n} \sum\limits_{j=0}^{i} S(i,j) \times 2^j \times j!$

其中$S(i,j)$为第二类斯特林数,公式为$S(i,j)=\frac{1}{j!} \sum\limits_{k=0}^{j} (-1)^k C(j,k) (j-k)^i$

求$f(n)$,$n<=100000$,答案对$998244353(=2^{23} \times 7 \times 17 + 1)$取模

 

 

$f(n)=\sum\limits_{i=0}^{n} \sum\limits_{j=0}^{i} 2^j \times \sum\limits_{k=0}^{j} (-1)^k \times \frac{j!}{k! \times (j-k)!} \times (j-k)^i$

$=\sum\limits_{i=0}^{n} \sum\limits_{j=0}^{i} 2^j \times j! \times \sum\limits_{k=0}^{j} \frac{(j-k)^i}{(j-k)!} \times \frac{(-1)^k}{k!}$

$=\sum\limits_{j=0}^{n} 2^j \times j! \times \sum\limits_{k=0}^{j} \frac{\sum\limits_{i=0}^{n}(j-k)^i}{(j-k)!} \times \frac{(-1)^k}{k!}$

可以发现,$\sum\limits_{i=0}^{n}(j-k)^i$项就是一个等比数列求和,可以快速幂求出。

那么两个分数分别只与j-k和k有关了,相乘的话,就是卷积形式FFT求出,枚举最外层j即可。

 

Update10/04:

终于抽出时间码完啦,少打了一个等号调了半天~

 1 #include<cstdio>
 2 #define mod 998244353
 3 #define int long long
 4 int rev[400005],bin=1,n,fac[100005],inv[100005],invv[100005],INV,sumpw[100005];
 5 int a[400005],b[400005],sum;
 6 int pow(int b,int t,int a=1){for(;t;t>>=1,b=b*b%mod)if(t&1)a=a*b%mod;return a;}
 7 void NTT(int *a,int opt){
 8     for(int i=1;i<bin;++i)if(i<rev[i])a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
 9     for(int mid=1,wn=pow(3,mod-1>>1);mid<bin;mid<<=1,wn=pow(3,(mod-1)/2/mid*opt+mod-1))
10         for(int i=0;i<bin;i+=mid<<1)
11             for(int j=0,w=1;j<mid;++j,w=w*wn%mod){
12                 int x=a[i+j],y=a[i+j+mid]*w%mod;
13                 a[i+j]=(x+y)%mod;a[i+j+mid]=(mod+x-y)%mod;
14             }
15     if(opt==-1)for(int i=0;i<bin;++i)a[i]=a[i]*INV%mod;
16 }
17 main(){
18     scanf("%lld",&n);
19     while(bin<=n<<1)bin<<=1;//printf("%lld\n",bin);
20     for(int i=1;i<bin;++i)rev[i]=rev[i>>1]>>1|(i&1)*bin>>1;
21     INV=pow(bin,mod-2);
22     fac[1]=inv[1]=invv[1]=fac[0]=inv[0]=sumpw[0]=1;
23     for(int i=2;i<=n;++i)fac[i]=fac[i-1]*i%mod,invv[i]=-mod/i*invv[mod%i]%mod+mod,inv[i]=inv[i-1]*invv[i]%mod;
24     sumpw[1]=n+1;for(int i=2;i<=n;++i)sumpw[i]=(pow(i,n+1)-1)*invv[i-1]%mod;
25     for(int i=0;i<=n;++i)a[i]=sumpw[i]*inv[i]%mod,b[i]=pow(mod-1,i)*inv[i]%mod;//,printf("%lld %lld\n",a[i],b[i]);
26     NTT(a,1);NTT(b,1);
27     for(int i=0;i<bin;++i)a[i]=a[i]*b[i]%mod;
28     NTT(a,-1);//for(int i=0;i<bin;++i)printf("%lld\n",a[i]);
29     for(int j=0;j<=n;++j)sum=(sum+pow(2,j)*fac[j]%mod*a[j])%mod;
30     printf("%lld\n",sum);
31 }
View Code
posted @ 2019-09-20 17:54  DeepinC  阅读(486)  评论(0编辑  收藏  举报