[ans=f(n)=sum_{i=0}^nsum_{j=0}^iS_i^j*2^j*j!,n1e5
]
第二类斯特林数
[S_m^n=sum_{i=0}^nfrac{(-1)^{n-i}*i^m}{i!(n-i)!}
]
[f(n)=sum_{i=0}^nsum_{j=0}^n2^j*j!sum_{k=0}^jfrac{(-1)^{j-k}*k^i}{k!(j-k)!}
]
[f(n)=sum_{j=0}^n2^jj!sum_{k=0}^j(frac{(-1)^{j-k}}{(j-k)!})(frac{sum_{i=0}^nk^i}{k!})
]
[sum_{i=0}^nk^i=frac{k^{n+1}-1}{k-1}
]
于是可以愉快地卷积了!时间复杂度(O(nlogn))
还有(O(n))的做法,还不是很会
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
#define ll long long
const int N=1e5+4,g=3,mod=998244353;
inline int ksm(int x,int r){
int ret=1;
for(int i=0;(1<<i)<=r;i++){
if((1<<i)&r)ret=(ll)ret*x%mod;
x=(ll)x*x%mod;
}
return ret;
}
int n,A[N<<2],B[N<<2],fac[N],inv[N],rev[N<<2];
inline void ntt(int *a,int fl,int lim,int len){
for(int i=0;i<len;i++){
rev[i]=(rev[i>>1]>>1)|((i&1)<<lim-1);
if(i<rev[i])swap(a[i],a[rev[i]]);
}
for(int mid=1,tmp,x,u,v;mid<len;mid<<=1){
tmp=ksm(g,(mod-1)/(mid<<1));
if(fl==-1)tmp=ksm(tmp,mod-2);
for(int i=0;i<len;i+=(mid<<1)){
x=1;
for(int j=0;j<mid;j++,x=(ll)x*tmp%mod){
u=a[i+j];v=(ll)a[i+j+mid]*x%mod;
a[i+j]=(u+v)%mod;a[i+j+mid]=(u-v+mod)%mod;
}
}
}
if(fl==-1)for(int i=0,tmp=ksm(len,mod-2);i<len;i++)
a[i]=(ll)a[i]*tmp%mod;
}
int main(){
n=read();
fac[0]=fac[1]=inv[0]=inv[1]=1;
for(int i=2;i<=n;i++)fac[i]=(ll)fac[i-1]*i%mod;
inv[n]=ksm(fac[n],mod-2);
for(int i=n-1;i>1;i--)inv[i]=(ll)inv[i+1]*(i+1)%mod;
for(int i=0;i<=n;i++){
A[i]=(ll)(i&1?mod-1:1)*inv[i]%mod;
B[i]=(ll)inv[i]*(ksm(i,n+1)+mod-1)%mod*ksm((i+mod-1)%mod,mod-2)%mod;
}
B[1]=n+1;//!
int lim=0,len=1,ans=0;
while(len<=(n<<1)){lim++;len<<=1;}
ntt(A,1,lim,len);ntt(B,1,lim,len);
for(int i=0;i<len;i++)A[i]=(ll)A[i]*B[i]%mod;
ntt(A,-1,lim,len);
for(int i=0,mi2=1;i<=n;i++,mi2=(mi2<<1)%mod)
ans=((ll)mi2*fac[i]%mod*A[i]+ans)%mod;
cout<<ans;
return (0-0);
}