P4091 [HEOI2016/TJOI2016]求和(第二类斯特林数,ntt)
作者:互联网
题面:https://www.luogu.org/problem/P4091
题解:\[\begin{array}{l}
f(n) = \sum\limits_{i = 0}^n {\sum\limits_{j = 0}^i {{\rm{S}}(i,j) \cdot {2^{\rm{j}}} \cdot j!} } \\
= \sum\limits_{i = 0}^n {\sum\limits_{j = 0}^n {{\rm{S}}(i,j) \cdot {2^{\rm{j}}} \cdot j!} }
\end{array}\]
把公式\[S(n,m) = \frac{{\sum\limits_{i = 0}^m {{{( - 1)}^i}{\rm{\cdot}}C_m^i} {\rm{\cdot}}{{(m - i)}^n}}}{{m!}}\]带进去
则\[{\rm{\backslash begin\{ array\} \{ l\} n\backslash begin\{ array\} \{ *\{ 20\} \{ l\} \} }}f(n) = \sum\limits_{i = 0}^n {\sum\limits_{j = 0}^n {{\rm{S}}(i,j) \cdot {2^{\rm{j}}} \cdot j!} = \sum\limits_{i = 0}^n {\sum\limits_{j = 0}^n {\sum\limits_{k = 0}^j {\frac{{{{( - 1)}^k}}}{{k!}} \cdot \frac{{{{(j - k)}^i}}}{{(j - k)!}}} \cdot {{\rm{2}}^{\rm{j}}}{\rm{\cdotj}}!} } } {\rm{n\{ }} = \sum {\rm{\_}}j = {\rm{\^}}n{\rm{ \{ }}{2^j}{\rm{\cdotj}}!\sum {\rm{\_}}k = 0{\rm{\^}}j{\rm{ \{ }}\sum {\rm{\_}}i = 0{\rm{\^}}n{\rm{ \{ }}\frac{{{{( - 1)}^k}}}{{k!}} \cdot \frac{{{{(j - k)}^i}}}{{(j - k)!}} = \sum {\rm{\_}}j = {\rm{\^}}n{\rm{ \{ }}{2^j}{\rm{\cdot}}j!\sum {\rm{\_}}k = 0{\rm{\^}}j{\rm{ \{ \backslash frac\{ \{ \{ }}( - 1){\rm{\^\{ \^}}k{\rm{\} \} \} \} }}k! \cdot {\rm{\} }}\frac{{\sum\limits_{i = 0}^n {{{(j - k)}^i}} }}{{(j - k)!}}{\rm{\} \} \} \} \} n\backslash end\{ array\} \backslash \backslash = }}\sum {\rm{\_}}j = {\rm{\^}}n{\rm{ \{ }}{2^j}{\rm{\cdot}}j!\sum {\rm{\_}}k = 0{\rm{\^}}j{\rm{ \{ \backslash frac\{ \{ \{ }}( - 1){\rm{\^\{ \^}}k{\rm{\} \} \} \} }}k! \cdot {\rm{\} }}\frac{{{{(j - k)}^{n + 1}} - 1}}{{(j - k)! \cdot (j - k - 1)}}{\rm{\} n\backslash end\{ array\} }}\]
令\[\begin{array}{l}
h(x) = \frac{{{{( - 1)}^x}}}{{x!}}\\
g(x) = \frac{{{x^{n + 1}} - 1}}{{x!{\rm{\cdot(x - 1)}}}}
\end{array}\]
后面的就是这两个的卷积,直接上ntt就行了
#include<bits/stdc++.h> #define ms(x) memset(x,0,sizeof(x)) #define sws ios::sync_with_stdio(false) using namespace std; typedef long long ll; const int maxn=5e5+5; const double pi=acos(-1.0); const ll mod=998244353;///通常情况下的模数, const ll g=3;///模数的原根998244353,1004535809,469762049 ll qpow(ll a,ll n,ll p){ ll ans=1; while(n){ if(n&1) ans=ans*a%p; n>>=1; a=a*a%p; } return ans; } int rev[maxn]; void ntt(ll a[],int n,int len,int pd){ rev[0]=0; for(int i=1;i<n;i++){ rev[i]=(rev[i>>1]>>1 | ((i&1)<<(len-1))); if(i<rev[i]) swap(a[i],a[rev[i]]); } for(int mid=1;mid<n;mid<<=1){ ll wn=qpow(g,(mod-1)/(mid*2),mod);///原根代替单位根 if(pd==-1) wn=qpow(wn,mod-2,mod);///逆变换则改成逆元 for(int j=0;j<n;j+=2*mid){ ll w=1; for(int k=0;k<mid;k++){ ll x=a[j+k],y=w*a[j+k+mid]%mod; a[j+k]=(x+y)%mod; a[j+k+mid]=(x-y+mod)%mod; w=w*wn%mod; } } } if(pd==-1){ ll inv=qpow(n,mod-2,mod); for(int i=0;i<n;i++){ a[i]=a[i]*inv%mod; } } } ll a[maxn],b[maxn],c[maxn]; void solve(int n,int m){ int len=0,up=1; while(up<=n+m) up<<=1,len++; ntt(a,up,len,1); ntt(b,up,len,1); for(int i=0;i<up;i++) c[i]=1ll*a[i]*b[i]%mod; ntt(c,up,len,-1); } ll fa[maxn]; int main(){ int n,m; sws; cin>>n; fa[0]=1; a[0]=1; b[0]=1; for(int i=1;i<=n;i++){ fa[i]=1ll*fa[i-1]*i%mod; int t=(i&1)==1?-1:1; a[i]=(t*qpow(fa[i],mod-2,mod)+mod)%mod; if(i==1) b[1]=n+1; else { b[i]=(qpow(i,n+1,mod)-1+mod)%mod*qpow(1ll*(i-1)*fa[i]%mod,mod-2,mod)%mod; } } solve(n,n); ll ans=0; for(ll i=0;i<=n;i++){ ans=(ans+qpow(2,i,mod)*fa[i]%mod*c[i]%mod)%mod; } cout<<ans<<endl; }
标签:frac,limits,cdot,sum,ntt,P4091,TJOI2016,rm,ll 来源: https://www.cnblogs.com/azznaz/p/11546388.html