loj 上的仙人掌计数时限 3s。此题可以用上题做法套个 exp,但是时限 2s。我在 loj 上跑了 2.7s,请求开大时限。
#include <bits/stdc++.h>
using namespace std;
namespace Le0{
#define il inline
const int mod=998244353,gg=3,N=3e5+5;
struct poly{
vector<int> a;
il int& operator[](int x){return a[x];}
il void re(int x){while(a.size()<x) a.push_back(0);}
il void cl(){vector<int> ().swap(a);}
}a,b;
int n,lim,ct,gi,T;
int rv[N],fac[N],ifac[N];
il int qp(int a,int b){
int as=1;
while(b){
if(b&1) as=1ll*as*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return as;
}
il void ntt(poly &a,int op){
for(int i=0;i<lim;i++) if(i<rv[i]) swap(a[i],a[rv[i]]);
for(int mid=1;mid<lim;mid<<=1){
int rt=qp(op==1?gg:gi,(mod-1)/(mid*2));
for(int j=0;j<lim;j+=mid*2){
int w=1;
for(int k=0;k<mid;k++){
int x=a[j+k],y=1ll*w*a[j+k+mid]%mod;
a[j+k]=(x+y)%mod,a[j+k+mid]=(x-y+mod)%mod;
w=1ll*w*rt%mod;
}
}
}
if(op==1) return;
int inv=qp(lim,mod-2);
for(int i=0;i<lim;i++) a[i]=1ll*a[i]*inv%mod;
}
il poly mul(poly a,poly b,int len){
lim=1,ct=-1;
while(lim<=(len-1)*2) lim<<=1,ct++;
for(int i=0;i<lim;i++) rv[i]=(rv[i>>1]>>1)|((i&1)<<ct);
a.re(lim);b.re(lim);
for(int i=len;i<lim;i++) a[i]=b[i]=0;
ntt(a,1);ntt(b,1);
for(int i=0;i<lim;i++) a[i]=1ll*a[i]*b[i]%mod;
ntt(a,-1);
for(int i=len;i<lim;i++) a[i]=0;
return a;
}
il void inv(poly a,poly &b,int len){
if(len==1){
b[0]=qp(a[0],mod-2);
return;
}
inv(a,b,len+1>>1);
poly G0=b,F=a;
F=mul(F,mul(G0,G0,len),len);
for(int i=0;i<len;i++) b[i]=(2ll*G0[i]%mod-F[i]+mod)%mod;
}
il void ln(poly &a,int len){
poly b;b.re(len);
inv(a,b,len);
poly c;c.re(len);
for(int i=0;i<len-1;i++) c[i]=1ll*a[i+1]*(i+1)%mod;
c=mul(c,b,len);
for(int i=1;i<len;i++) a[i]=1ll*c[i-1]*qp(i,mod-2)%mod;
a[0]=0;
}
il void exp(poly a,poly &b,int len){
if(len==1){
b[0]=1;
return;
}
exp(a,b,len+1>>1);
poly f=b;ln(f,len);
a[0]++;
for(int i=0;i<len;i++) f[i]=(mod-f[i]+a[i])%mod;
b=mul(b,f,len);
}
il void Newton(poly &a,int len){
if(len==1) return;
Newton(a,len+1>>1);
poly a2=mul(a,a,len);
poly F,iF;F.re(len);iF.re(len);
for(int i=0;i<len;i++) F[i]=mod-2ll*a[i]%mod;
F[0]+=2;
inv(F,iF,len);
poly F2=mul(F,F,len);
poly iF2;iF2.re(len);
inv(F2,iF2,len);
poly b;b.re(len);
for(int i=0;i<len;i++) b[i]=(2ll*a[i]%mod-a2[i]+mod)%mod;
b=mul(b,iF,len);
poly c;c.re(len);
exp(b,c,len);
poly res;res.re(len);
for(int i=1;i<len;i++) res[i]=c[i-1];
poly d;d.re(len);
for(int i=0;i<len;i++) d[i]=(4ll*a[i]%mod-2ll*a2[i]%mod+mod)%mod;
d=mul(d,iF2,len);d[0]++;
d=mul(d,res,len);
for(int i=0;i<len;i++) d[i]=mod-d[i];
d[0]++;
poly id;id.re(len);
inv(d,id,len);
for(int i=0;i<len;i++) res[i]=(a[i]-res[i]+mod)%mod;
res=mul(res,id,len);
for(int i=0;i<len;i++) a[i]=(a[i]-res[i]+mod)%mod;
}
void init(){
fac[0]=ifac[0]=1;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
ifac[n]=qp(fac[n],mod-2);
for(int i=n-1;i>=1;i--) ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
}
int main(){
cin>>n;gi=qp(gg,mod-2);
a.re(n+1);b.re(n+1);
init();
Newton(a,n+1);
for(int i=1;i<=n;i++) a[i]=1ll*a[i]*qp(i,mod-2)%mod;
exp(a,b,n+1);
cout<<1ll*b[n]*fac[n]%mod<<'\n';
return 0;
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
return Le0::main();
}