【xsy1301】 原题的价值 组合数+斯特林数+FFT

题目大意:求$n\times2^{\frac{(n-1)(n-2)/2}{2}}\sum\limits_{i=0}^{n-1}\dbinom{n-1}{i}i^k$

数据范围:$n≤10^9$,$k≤10^5$,答案对$998244353$取模。


 

我们令$F(n,k)=\sum\limits_{i=0}^{n-1}\binom{n-1}{i}i^k$。

那么最终要输出的东西显然就是$n\times2^{\frac{(n-1)(n-2)/2}{2}}F(n,k)$

我们令$G(n,k)=(n-1)^\underline{k}2^{n-1-k}$

 

我们先考虑下当$k=0$的时候要怎么做,我们显然有:

$F(n,0)=\sum\limits_{i=0}^{n-1}\binom{n-1}{i}=2^{n-1}$

化简是根据二项式定理来的,在此不展开说了。

 

考虑下当$k=1$的时候要怎么做:

$F(n,1)=\sum\limits_{i=0}^{n-1}\dbinom{n-1}{i}i
\\
=\sum\limits_{i=0}^{n-1}\dfrac{(n-1)!}{i!(n-1-i)!}i
\\
=\sum\limits_{i=1}^{n-1}\dfrac{(n-1)!}{(i-1)!(n-1-i)!}
\\
=\sum\limits_{i=1}^{n-1}\dfrac{(n-1)!}{(i-1)!((n-2)-(i-1))!}
\\
=(n-1)\sum\limits_{i=1}^{n-1}\dfrac{(n-2)!}{(i-1)!((n-2)-(i-1))!}
\\
=(n-1)\sum\limits_{i=1}^{n-1}\dbinom{n-2}{i-1}
\\
=(n-1)F(n-1,0)=G(n,1)$

 

我们考虑按照$k=1$的化简方法来化简$k=2$,由于跟上文比较相似,所以可能会有不少的跳步

$F(n,2)=\sum\limits_{i=0}^{n-1}\dbinom{n-1}{i}i^2$

$=\sum\limits_{i=0}^{n-1}\dfrac{(n-1)!}{i!(n-1-i)!}i^2$

$=(n-1)\sum\limits_{i=1}^{n-1}\dbinom{n-2}{i-1}i$

$=(n-1)\sum\limits_{i=1}^{n-1}\dfrac{(n-2)!}{(i-1)!\big((n-2)-(i-1)\big)!}\big((i-1)+1\big)$

$=F(n-1,1)+(n-1)\sum\limits_{i=1}^{n-1}\dfrac{(n-2)!}{(i-2)!\big((n-3)-(i-2)\big)!}$

$=F(n-1,1)+(n-1)(n-2)\sum\limits_{i=1}^{n-1}\dfrac{(n-3)!}{(i-2)!\big((n-3)-(i-2)\big)!}$

$=F(n-1,1)+(n-1)(n-2)F(n-2,0)$

$=G(n,1)+G(n,2)$

 

 
根据k=2的推法,我们推出了$k=3$和$k=4$的情况:

$F(n,3)=G(n,1)+3G(n,2)+4G(n,3)$

$F(n,4)=G(n,1)+7G(n,2)+6G(n,3)+G(n,4)$

诶?这不是斯特林三角形吗(证明显然,这里不证了)

 

于是有:

$F(n,m)=\sum\limits_{i=1}^{m}S2(n,i)G(n,i)$

$G(n,1\cdots k)$可以在$O(k)$的时间复杂度内求出来,$S2(n,1\cdots k)$可以在$O(k\log\ k)$的复杂度内用FFT求出来。

完结撒花~

 

 

 1 #include<bits/stdc++.h>
 2 #define MOD 998244353
 3 #define L long long
 4 #define M (1<<18)
 5 #define G 3
 6 using namespace std;
 7 
 8 L fac[M]={0},invfac[M]={0};
 9 L pow_mod(L x,L k){L ans=1;for(;k>0;k>>=1,x=x*x%MOD) if(k&1) ans=ans*x%MOD; return ans;}
10 L C(int n,int m){return fac[n]*invfac[m]%MOD*invfac[n-m]%MOD;}
11 
12 void change(L a[],int n){
13     for(int i=0,j=0;i<n-1;i++){
14         if(i<j) swap(a[i],a[j]);
15         int k=n>>1;
16         while(j>=k) j-=k,k>>=1;
17         j+=k;
18     }
19 }
20 void NTT(L a[],int n,int on){
21     change(a,n);
22     for(int h=2;h<=n;h<<=1){
23         L wn=pow_mod(G,(MOD-1)/h);
24         for(int j=0;j<n;j+=h){
25             L w=1;
26             for(int k=j;k<j+(h>>1);k++){
27                 L u=a[k],t=a[k+(h>>1)]*w%MOD;
28                 a[k]=(u+t)%MOD;
29                 a[k+(h>>1)]=(u-t+MOD)%MOD;
30                 w=w*wn%MOD;
31             }
32         }
33     }
34     if(on==-1){
35         reverse(a+1,a+n);
36         L INV=pow_mod(n,MOD-2);
37         for(int i=0;i<n;i++) a[i]=a[i]*INV%MOD;
38     }
39 }
40 L a[M]={0},b[M]={0},s[M]={0},nc[M]={0};
41 
42 int main(){
43     fac[0]=1; for(int i=1;i<M;i++) fac[i]=fac[i-1]*i%MOD;
44     invfac[M-1]=pow_mod(fac[M-1],MOD-2);
45     for(int i=M-2;~i;i--) invfac[i]=invfac[i+1]*(i+1)%MOD;
46     L n,k,ans=0; cin>>n>>k;
47     if(k==0) return printf("%lld\n",n*pow_mod(2,(n-1)*n/2)%MOD);
48     for(L i=0,mul=1;i<k;i++){
49         mul=mul*(n-i-1)%MOD;
50         nc[i+1]=mul*pow_mod(2,n-i-2)%MOD;
51     }
52     for(int i=0;i<=k;i++){
53         a[i]=pow_mod(MOD-1,i)*invfac[i]%MOD;
54         b[i]=pow_mod(i,k)*invfac[i]%MOD;
55     }
56     int len=1; while(k*2>=len) len<<=1;
57     NTT(a,len,1); NTT(b,len,1);
58     for(int i=0;i<len;i++) s[i]=a[i]*b[i]%MOD;
59     NTT(s,len,-1);
60     for(int i=k+1;i<len;i++) s[i]=0;
61     
62     for(int i=1;i<=k;i++)
63     (ans+=nc[i]*s[i])%=MOD;
64     
65     cout<<ans*n%MOD*pow_mod(2,(n*(n-1)/2-(n-1)))%MOD<<endl;
66 }

 

posted @ 2019-05-04 18:06  AlphaInf  阅读(310)  评论(0编辑  收藏  举报