为什么长度是 n 做会WA20,如果长度是 2×n 就过了啊。
递归写法,ln 是贺模板的。
#include<bits/stdc++.h>
using namespace std;
const int N=8e5+5,mod=998244353,G=3;
int kuai(int a,int b){
int ans=1;
for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;
return ans;
}
int S,cnt[N],Gi;
void NTT(int *A,int T){
for(int i=0;i<=S;i++)if(i<cnt[i])swap(A[i],A[cnt[i]]);
for(int len=1;len<S;len<<=1){
int W=kuai(T?G:Gi,(mod-1)/(len*2));
for(int L=0;L<S;L+=len*2){
int now=1;
for(int k=0;k<len;k++,now=1ll*now*W%mod){
int x=A[L+k],y=1ll*A[L+len+k]*now%mod;
A[L+k]=(x+y)%mod,A[L+len+k]=(x-y+mod)%mod;
}
}
}
}
int l,A[N],B[N];
void mul(int *a,int *b,int *ans,int n,int m,int p){
for(S=1,l=0;S<=n+m;S<<=1,l++);
for(int i=0;i<=S;i++)A[i]=B[i]=0;
for(int i=0;i<=n;i++)A[i]=a[i];
for(int i=0;i<=m;i++)B[i]=b[i];
for(int i=1;i<=S;i++)cnt[i]=(cnt[i>>1]>>1)+((i&1)<<(l-1));
NTT(A,1),NTT(B,1);
for(int i=0;i<=S;i++)A[i]=1ll*A[i]*B[i]%mod;
NTT(A,0);
int Inv=kuai(S,mod-2);
for(int i=0;i<p;i++)ans[i]=1ll*A[i]*Inv%mod;
}
void Dao(int *a,int *ans,int n){
for(int i=0;i<=n;i++)A[i]=a[i],ans[i]=0;
for(int i=0;i<n;i++)ans[i]=1ll*A[i+1]*(i+1)%mod;
}
void Ji(int *a,int *ans,int n){
for(int i=0;i<=n;i++)A[i]=a[i],ans[i]=0;
for(int i=1;i<=n;i++)ans[i]=1ll*A[i-1]*kuai(i,mod-2)%mod;
}
int h[N];
void get_Inv(int *a,int *f,int n){
if(n==1){f[0]=1;return;}
int mid=(n+1)/2;
get_Inv(a,f,mid);
mul(f,f,h,mid,mid,n),mul(h,a,h,n,n,n);
for(int i=0;i<n;i++)f[i]=(2ll*f[i]%mod-h[i]+mod)%mod;
}
int g[N],f[N];
void get_Ln(int *a,int *ans,int n){get_Inv(a,f,n),Dao(a,g,n),mul(g,f,g,n,n,n),Ji(g,ans,n);}
int F[N];
void get_Exp(int *a,int *ans,int n){
if(n==1){ans[0]=1;return;}
get_Exp(a,ans,(n+1)/2);
get_Ln(ans,F,n);
for(int i=0;i<n;i++)F[i]=(a[i]-F[i]+mod)%mod;
F[0]++;
mul(ans,F,ans,n,n,n);
}
int n,a[N],ans[N];
int main(){
Gi=kuai(G,mod-2);
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
get_Exp(a,ans,2*n);//此处写2*n AC,写n WA
for(int i=0;i<n;i++)printf("%d ",ans[i]);
}