4555: [Tjoi2016&Heoi2016]求和
Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 580 Solved: 458
[Submit][Status][Discuss]
Description
在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心。
现在他想计算这样一个函数的值:

S(i, j)表示第二类斯特林数,递推公式为:
S(i, j) = j ∗ S(i − 1, j) + S(i − 1, j − 1), 1 <= j <= i − 1。
边界条件为:S(i, i) = 1(0 <= i), S(i, 0) = 0(1 <= i)
你能帮帮他吗?
Input
输入只有一个正整数
Output
输出f(n)。由于结果会很大,输出f(n)对998244353(7 × 17 × 223 + 1)取模的结果即可。1 ≤ n ≤ 100000
Sample Input
3
Sample Output
87
这题挺妙的
写的时候虎了一下
卷积之前把一个数组 reverse 了 之后直接卷错了
下面转了一个题解 连为啥没做出来都和那个博主一样...
以下部分转载自https://www.cnblogs.com/enigma-aw/p/6580546.html
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=300100,mod=998244353;
inline int qpow(int x,int y)
{
int res(1);
while(y)
{
if(y&1) res=1ll*res*x%mod;
x=1ll*x*x%mod;
y>>=1;
}
return res;
}
int r[N];
void ntt(int *x,int lim,int opt)
{
register int i,j,k,m,g,gn,tmp;
for(i=0;i<lim;++i)
if(r[i]<i)
swap(x[i],x[r[i]]);
for(m=2;m<=lim;m<<=1)
{
k=m>>1;
gn=qpow(3,(mod-1)/m);
for(i=0;i<lim;i+=m)
{
g=1;
for(j=0;j<k;++j,g=1ll*g*gn%mod)
{
tmp=1ll*x[i+j+k]*g%mod;
x[i+j+k]=(x[i+j]-tmp+mod)%mod;
x[i+j]=(x[i+j]+tmp)%mod;
}
}
}
if(opt==-1)
{
reverse(x+1,x+lim);
int inv(qpow(lim,mod-2));
for(i=0;i<lim;++i) x[i]=1ll*x[i]*inv%mod;
}
}
int A[N],B[N],C[N];
int fac[N],inv[N];
int main()
{
int n=read();
register int i,j,lim(1);
fac[0]=1;for(i=1;i<=n;++i) fac[i]=1ll*fac[i-1]*i%mod;
inv[1]=1;for(i=2;i<=n;++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(i=2;i<=n;++i) B[i]=inv[i-1];
inv[0]=1;for(i=1;i<=n;++i) inv[i]=1ll*inv[i]*inv[i-1]%mod;
for(i=0;i<=n;++i)
A[i]=i&1 ? mod-inv[i] : inv[i];
B[0]=1;B[1]=n+1;
for(i=2;i<=n;++i)
B[i]=1ll*B[i]*inv[i]%mod*(qpow(i,n+1)-1+mod)%mod;
while(lim<=(n<<1)) lim<<=1;
for(i=0;i<lim;++i) r[i]=(i&1)*(lim>>1)+(r[i>>1]>>1);
ntt(A,lim,1);ntt(B,lim,1);
for(i=0;i<lim;++i)
C[i]=1ll*A[i]*B[i]%mod;
ntt(C,lim,-1);
int ans(0);j=1;
for(i=0;i<=n;++i,(j<<=1)%=mod)
(ans+=1ll*j*fac[i]%mod*C[i]%mod)%=mod;
cout<<ans<<endl;
return 0;
}