第二类斯特林数 S(i,j) S ( i , j ) 代表 i i 个数分成个集合的方案数
f(n)=∑ni=0∑ij=0S(i,j)∗2j∗j! f ( n ) = ∑ i = 0 n ∑ j = 0 i S ( i , j ) ∗ 2 j ∗ j !
这里的
S(i,j)∗2j∗j!
S
(
i
,
j
)
∗
2
j
∗
j
!
可以理解成i个数分成j个集合,考虑顺序,每个集合有2种状态的方案数
记
g(n)=∑ni=0S(n,i)∗2i∗i!
g
(
n
)
=
∑
i
=
0
n
S
(
n
,
i
)
∗
2
i
∗
i
!
,即n个数分成若干个集合,考虑顺序,每个集合有2种状态方案数
枚举最后一个集合的个数,得到g(n)的递推式
g(n)=∑ni=12∗Cing(n−i)
g
(
n
)
=
∑
i
=
1
n
2
∗
C
n
i
g
(
n
−
i
)
展开组合数
得:
g(n)=2∗∑ni=1n!i!(n−i)!g(n−i)
g
(
n
)
=
2
∗
∑
i
=
1
n
n
!
i
!
(
n
−
i
)
!
g
(
n
−
i
)
于是 g(n)n!=∑ni=12i!g(n−i)(n−i)! g ( n ) n ! = ∑ i = 1 n 2 i ! g ( n − i ) ( n − i ) !
令
G(x)=∑∞i=0g(i)i!xi,H(x)=∑∞i=12i!xi
G
(
x
)
=
∑
i
=
0
∞
g
(
i
)
i
!
x
i
,
H
(
x
)
=
∑
i
=
1
∞
2
i
!
x
i
有
G=G∗H+1
G
=
G
∗
H
+
1
于是
G=(1−H)−1
G
=
(
1
−
H
)
−
1
然后多项式求逆就好了
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 410000;
const ll Mod = 998244353;
const ll g = 3;
int n,N;
ll inv[maxn];
ll w[maxn],G[maxn],H[maxn],t[maxn];
int id[maxn];
ll pw(ll x,int k)
{
ll re=1;
for(;k;k>>=1,x=(x*x)%Mod)
if(k&1) (re*=x)%=Mod;
return re;
}
void pre(const int u,const int ln)
{
for(int i=0;i<u;i++) id[i]=(id[i>>1]>>1)|((i&1)<<ln-1);
w[0]=1ll,w[1]=pw(g,(Mod-1)/u);
for(int i=2;i<=u;i++) w[i]=w[i-1]*w[1]%Mod;
}
void DFT(ll s[],const int u,const int sig)
{
for(int i=0;i<u;i++) if(i<id[i]) swap(s[i],s[id[i]]);
for(int m=2;m<=u;m<<=1)
{
int t=m>>1,tt=u/m;
for(int i=0;i<t;i++)
{
ll wn=sig==1?w[i*tt]:w[u-i*tt];
for(int j=i;j<u;j+=m)
{
ll tx=s[j],ty=s[j+t]*wn%Mod;
s[j]=(tx+ty)%Mod;
s[j+t]=(tx-ty)%Mod;
}
}
}
if(sig==-1)
{
ll tt=inv[u];
for(int i=0;i<u;i++) s[i]=(s[i]*tt%Mod+Mod)%Mod;
}
}
void get_inv(ll a[],ll b[],const int u,const int ln)
{
if(u==1)
{
b[0]=pw(a[0],Mod-2);
return;
}
get_inv(a,b,u>>1,ln-1);
pre(u<<1,ln+1);
for(int i=0;i<u;i++) t[i]=a[i],t[i+u]=0;
DFT(t,u<<1,1); DFT(b,u<<1,1);
for(int i=0;i<(u<<1);i++) t[i]=b[i]*(2ll-t[i]*b[i]%Mod)%Mod;
DFT(t,u<<1,-1);
for(int i=0;i<u;i++) b[i]=t[i],b[i+u]=0;
}
ll solve()
{
int ln=0; N=1; while(N<=n) N<<=1,ln++;
inv[1]=1ll;
for(ll i=2;i<=(N<<1);i++)
inv[i]=(Mod-Mod/i)*inv[Mod%i]%Mod;
H[1]=2ll; for(int i=2;i<=n;i++) H[i]=H[i-1]*inv[i]%Mod;
for(int i=1;i<=n;i++) H[i]=-H[i]+Mod; H[0]=1ll;
get_inv(H,G,N,ln);
ll re=G[0],ss=1ll;
for(int i=1;i<=n;i++)
{
(ss*=(ll)i)%=Mod;
(re+=G[i]*ss%Mod)%=Mod;
}
if(re<0) re+=Mod;
return re;
}
int main()
{
scanf("%d",&n);
printf("%lld\n",solve());
return 0;
}