听说NOIP要考NTT于是赶快学了一发(大雾)。
Part.1 多项式卷积
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
typedef long long LL;
inline int read(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x;
}
const int MAXN=2100005;
const LL p=998244353,g=3,invg=332748118;
int n,m,l,rev[MAXN];
LL a[MAXN],b[MAXN],inv;
inline LL qpow(LL x,LL y){
LL ret=1,t=x%p;
while(y){
if(y&1) ret=ret*t%p;
t=t*t%p;
y>>=1;
}
return ret;
}
inline void NTT(LL* c,int dft){
for(int i=0;i<n;i++)
if(i<rev[i]) std::swap(c[i],c[rev[i]]);
for(int mid=1;mid<n;mid<<=1){
int r=(mid<<1);LL u=qpow(dft>0?g:invg,(p-1)/r);
for(int l=0;l<n;l+=r){
LL v=1;
for(int i=0;i<mid;i++,v=v*u%p){
LL x=c[l+i],y=v*c[l+mid+i]%p;
c[l+i]=(x+y<p?x+y:x+y-p);
c[l+mid+i]=(x-y<0?x-y+p:x-y);
}
}
}
if(dft<0) for(int i=0;i<n;i++)
c[i]=c[i]*inv%p;
}
int main(){
n=read(),m=read();
for(int i=0;i<=n;i++) a[i]=read();
for(int i=0;i<=m;i++) b[i]=read();
for(m+=n,n=1;n<=m;n<<=1) l++;
inv=qpow(n,p-2);
for(int i=0;i<n;i++) rev[i]=((rev[i>>1]>>1)|((i&1)<<(l-1)));
NTT(a,1);NTT(b,1);
for(int i=0;i<n;i++) a[i]=a[i]*b[i]%p;
NTT(a,-1);
for(int i=0;i<=m;i++) printf("%lld ",a[i]);
printf("\n");
return 0;
}
Reference:https://riteme.github.io/blog/2016-8-22/ntt.html