NTT(快速数论变换)用到的各种素数及原根:
https://blog.csdn.net/hnust_xx/article/details/76572828
NTT多项式乘法模板
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; const LL mod=998244353; //119*2^23+1 g=3 const int N=(1<<19)+2; const int g=3; int rev[N]; LL a[N],b[N]; template<typename T> void read(T &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } LL Pow(LL a,LL b) { LL res=1; for(;b;a=a*a%mod,b>>=1) if(b&1) res=res*a%mod; return res; } void NTT(LL *a,int n,int f) { for(int i=0;i<n;++i) if(i<rev[i]) swap(a[i],a[rev[i]]); for(int i=1;i<n;i<<=1) { LL wn=Pow(g,(mod-1)/(i*2)); if(f<0) wn=Pow(wn,mod-2); for(int j=0,p=i<<1;j<n;j+=p) { LL w=1; for(int k=0;k<i;++k,w=w*wn%mod) { int x=a[j+k],y=w*a[j+k+i]%mod; a[j+k]=(x+y)%mod; a[j+k+i]=(x-y+mod)%mod; } } } if(f<0) { LL inv=Pow(n,mod-2); for(int i=0;i<n;++i) a[i]=a[i]*inv%mod; } } int main() { int nn,mm; read(nn); read(mm); for(int i=0;i<=nn;++i) read(a[i]); for(int i=0;i<=mm;++i) read(b[i]); int l=0,len=nn+mm; int n; for(n=1;n<=len;n<<=1) l++; for(int i=0;i<n;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<l-1); NTT(a,n,1); NTT(b,n,1); for(int i=0;i<n;++i) a[i]=a[i]*b[i]%mod; NTT(a,n,-1); for(int i=0;i<=len;++i) printf("%lld ",a[i]); }