NTT快速数论变换

Posted wendigo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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," 
"[i==n+m]);
	return 0;
}

以上是关于NTT快速数论变换的主要内容,如果未能解决你的问题,请参考以下文章

模板 NTT 快速数论变换

快速数论变换NTT模板

NTT快速数论变换

NTT

FFT/NTT/FMT/FWT题目

FFT/NTT/FMT/FWT题目