[egin{aligned}
ans&=sumlimits_{i=0}^nsumlimits_{j=0}^ileft{iatop j
ight}2^jj!\
&=sumlimits_{i=0}^nsumlimits_{j=0}^nleft{iatop j
ight}2^jj!\
&=sumlimits_{i=0}^nsumlimits_{j=0}^n2^jsumlimits_{k=0}^j(-1)^{j-k}{jchoose k}k^i\
&=sumlimits_{i=0}^nsumlimits_{j=0}^n2^jsumlimits_{k=0}^j(-1)^{j-k}{jchoose k}k^i\
&=sumlimits_{j=0}^nsumlimits_{k=0}^j(-1)^{j-k}{jchoose k}2^j[n+1]_k\
&=sumlimits_{k=0}^n[n+1]_ksumlimits_{i=k}^n(-1)^{i-k}{ichoose k}2^i\
&=sumlimits_{k=0}^n(-1)^k[n+1]_ksumlimits_{i=k}^n(-2)^i{ichoose k}end{aligned}
]
设(a_i=sumlimits_{j=i}^n(-2)^j{jchoose i}),那么(ans=sumlimits_{k=0}^n(-1)^k[n+1]_ka_k)。
([n+1]_k)是可以利用线性筛求出来的,那么我们现在考虑如何线性求出(a)。
(a_0)是可以轻松线性计算的,那么我们考虑递推。
[egin{aligned}
a_i&=sumlimits_{j=i}^n(-2)^j{jchoose i}\
&=sumlimits_{j=i}^n(-2)^j({j-1choose i}+{j-1choose i-1})\
&=(-2)(sumlimits_{j=i}^{n-1}(-2)^j{jchoose i}+sumlimits_{j=i-1}^{n-1}(-2)^j{jchoose i-1})\
&=-2(a_i+a_{i-1})+2(-2)^n{n+1choose i}\
&=frac23((-2)^n{n+1choose i}-a_{i-1})
end{aligned}
]
很显然预处理阶乘就可以线性计算了。
#include<cstdio>
const int N=100007,P=998244353;
int fac[N],ifac[N],inv[N],pw[N],is[N],pr[N],pw2[N],a[N];
void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
void dec(int&a,int b){a-=b,a+=a>>31&P;}
int mul(int a,int b){return 1ll*a*b%P;}
int pow(int a,int b){int r=1;for(;b;b>>=1,a=mul(a,a))if(b&1)r=mul(a,r);return r;}
int C(int n,int m){return 1ll*fac[n]*ifac[n-m]%P*ifac[m]%P;}
int main()
{
int n,m=0,ans=0;scanf("%d",&n),fac[0]=fac[1]=ifac[0]=ifac[1]=inv[0]=inv[1]=pw2[0]=1,pw2[1]=P-2;
for(int i=2;i<=n;++i)
{
if(!is[i]) pr[++m]=i,pw[i]=pow(i,n+1);
for(int j=1;pr[j]*i<=n;++j){is[i*pr[j]]=1,pw[i*pr[j]]=mul(pw[i],pw[pr[j]]);if(!(i%pr[j]))break;}
}
for(int i=2;i<=n+3;++i) fac[i]=mul(fac[i-1],i),ifac[i]=mul(ifac[i-1],inv[i]=mul(P-P/i,inv[P%i])),pw2[i]=mul(pw2[i-1],P-2);
for(int i=0;i<=n;++i) inc(a[0],pw2[i]);
for(int i=1;i<=n;++i) a[i]=2ll*inv[3]*(1ll*pw2[n]*C(n+1,i)%P-a[i-1]+P)%P;
for(int i=2;i<=n;++i) (i&1? dec:inc)(ans,(pw[i]-1ll)*a[i]%P*inv[i-1]%P);
inc(ans,a[0]),dec(ans,mul(a[1],n+1)),printf("%d",ans);
}