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快速数论变换的主要内容,如果未能解决你的问题,请参考以下文章