NTT快速数论变换

咕咕咕,放个模板:

//Data
const int N=4e6,mod=998244353,iv3=332748118;
int n,m,lim=1,ln,ivl,r[N+7];
vector<lng> f(N+7),g(N+7),ans(N+7);
lng Pow(lng a,lng x){
	if(a==0) return 0; x%=mod-1; lng res(1);
	for(;x;(a*=a)%=mod,x>>=1)if(x&1) (res*=a)%=mod;
	return res;
}

//NTT
void NTT(vector<lng>&f,int t){
	for(int i=0;i<lim;i++)if(i<r[i]) swap(f[i],f[r[i]]);
	for(int mid=1;mid<lim;mid<<=1){
		lng wn=Pow(t==1?3:iv3,(mod-1)/(mid<<1)),w;
		for(int j=0;j<lim;j+=(mid<<1)){
			w=1;
			for(int k=j;k<mid+j;(w*=wn)%=mod,k++){
				int x=f[k],y=w*f[mid+k]%mod;
				f[k]=(x+y)%mod,f[mid+k]=(x-y+mod)%mod;
			}
		}
	}
}

//Main
int main(){
	n=ri,m=ri;
	for(int i=0;i<=n;i++) f[i]=ri;
	for(int i=0;i<=m;i++) g[i]=ri;
	while(lim<=n+m) lim<<=1,ln++; ivl=Pow(lim,mod-2);
	for(int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(ln-1));
	NTT(f,1),NTT(g,1);
	for(int i=0;i<lim;i++) ans[i]=(f[i]*g[i])%mod;
	NTT(ans,-1);
	for(int i=0;i<=n+m;i++) printf("%lld%c",(ans[i]*ivl)%mod," \n"[i==n+m]);
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/Wendigo/p/12790401.html