【模板】 多项式乘法

学习一波NTT 放弃FFT

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #define rep(i,s,t) for(register int i=(s);i<=(t);++i)
11 #define dwn(i,s,t) for(register int i=(s);i>=(t);--i)
12 #define ren for(register int i=fst[x];i;i=nxt[i])
13 #define Fill(x,t) memset(x,t,sizeof(x))
14 #define ll long long
15 #define inf 2139062143
16 #define MOD 998244353
17 #define MAXN 2001000
18 using namespace std;
19 inline int read()
20 {
21     int x=0,f=1;char ch=getchar();
22     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
23     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
24     return x*f;
25 }
26 int n,m,lg,lmt;
27 ll A[MAXN<<2],B[MAXN<<2],rev[MAXN<<2];
28 ll q_pow(ll bas,ll t,ll res=1)
29 {
30     for(;t;t>>=1,(bas*=bas)%=MOD)
31         if(t&1) (res*=bas)%=MOD;return res;
32 }
33 void ntt(ll *a,int n,int f)
34 {
35     rep(i,0,n-1) if(i<rev[i])swap(a[i],a[rev[i]]);
36     for(int i=1;i<n;i<<=1)
37     {
38         ll wn=q_pow(3,(MOD-1)/(i<<1))%MOD;
39         if(f==-1)wn=q_pow(wn,MOD-2);
40         for(int j=0;j<n;j+=i<<1)
41         {
42             ll w=1,x,y;
43             for(int k=0;k<i;k++,w=wn*w%MOD)
44                 x=a[k+j],y=((ll)a[k+j+i]*w)%MOD,a[j+k]=(x+y)%MOD,a[j+k+i]=(x-y+MOD)%MOD;
45         }
46     }
47     if(f==1) return ;int nv=q_pow(n,MOD-2);
48     for(int i=0;i<n;i++) a[i]=a[i]*nv%MOD;
49 }
50 int main()
51 {
52     n=read()+1,m=read()+1;rep(i,0,n-1) A[i]=read();rep(i,0,m-1) B[i]=read();
53     lg=ceil(log2(n+m)),lmt=1<<lg;
54     rep(i,0,lmt-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
55     ntt(A,lmt,1);ntt(B,lmt,1);rep(i,0,lmt-1) (A[i]*=B[i])%=MOD;
56     ntt(A,lmt,-1);rep(i,0,n+m-2) printf("%lld ",A[i]);
57 }
View Code

相关文章: