分治FFT模板(无讲解)

P4721 【模板】分治 FFT

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rint register int
inline int rd(){
   int x=0,f=1;
   char ch=getchar();
   while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
   while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
   return x*f;
}
const int N=400010;
const int mod=998244353;
int n,g[N],f[N],a[N],b[N],rev[N],lim,lg;
LL qpow(LL n,LL k) {
	LL res=1;for(;k;k>>=1,n=n*n%mod)if(k&1)res=res*n%mod;return res;
}
void NTT(int *a,int g,int n) {
	for(rint i=0;i<n;++i)
		if(i>rev[i])swap(a[i],a[rev[i]]);
	for(rint i=1;i<n;i<<=1) {
		int wn=qpow(g,(mod-1)/(i<<1));
		for(rint j=0;j<n;j+=(i<<1)) {
			int w0=1;
			for(rint k=0;k<i;++k,w0=(1ll*w0*wn)%mod) {
				int X=a[j+k],Y=1ll*w0*a[i+j+k]%mod;
				a[j+k]=(X+Y)%mod;
				a[i+j+k]=(X-Y+mod)%mod;
			}
		}
	}
}
void CDQ_NTT(int l,int r) {
	if(l==r)return;
	int mid=(l+r)>>1;
	CDQ_NTT(l,mid);
	int mx=r-l+1;
	for(lg=0,lim=1;lim<=mx;lim<<=1,++lg);
	for(rint i=0;i<lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)),a[i]=b[i]=0;
	for(rint i=l;i<=mid;++i)a[i-l]=f[i];
	for(rint i=1;i<=r-l;++i)b[i-1]=g[i];
	NTT(a,3,lim),NTT(b,3,lim);
	for(rint i=0;i<lim;++i)a[i]=1ll*a[i]*b[i]%mod;
	NTT(a,qpow(3,mod-2),lim);
	for(rint i=0,inv=qpow(lim,mod-2);i<lim;++i)a[i]=1ll*a[i]*inv%mod;
	for(rint i=mid+1;i<=r;++i)f[i]=(f[i]+a[i-l-1])%mod;
	CDQ_NTT(mid+1,r);
}
signed main() {
	n=rd();f[0]=1;
	for(rint i=1;i<n;++i)g[i]=rd()%mod;
	CDQ_NTT(0,n-1);
	for(rint i=0;i<n;++i)printf("%d ",f[i]);
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/zzctommy/p/12550550.html