(FFT)
递归版
#include<iostream>
#include<cstdio>
#include<complex>
#define ll long long
#define comp std::complex<double>
#define fft fast_fast_tle
const int N = (1 << 20) + 10 << 1;
const double PI2 = 2.0 * std::acos(-1.0);
inline ll read(){
ll ans = 0;
char a = getchar();
while(!(a <= '9' && a >= '0'))a = getchar();
while(a <= '9' && a >= '0')
ans = (ans << 3) + (ans << 1) + (a & 15),a = getchar();
return ans;
}
int n,m;
comp a[N],b[N];
void fft(int n,comp * a,int type){
if(n == 1)return;
comp a1[n >> 1],a2[n >> 1];
for(int i = 0;i < n;i += 2)
a1[i >> 1] = a[i],a2[i >> 1] = a[i + 1];
fft(n >> 1,a1,type),fft(n >> 1,a2,type);
comp w(1,0),wn(cos(PI2 / n),type * sin(PI2 / n));
for(int i = 0;i < n >> 1;++i,w *= wn)
a[i] = a1[i] + w * a2[i],a[i + (n >> 1)] = a1[i] - w * a2[i];
}
//Fast_Fast_Tle
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();
ll lim = 1;
for(;lim <= n + m;lim <<= 1);
fft(lim,a,1),fft(lim,b,1);
for(int i = 0;i <= lim;++i)
a[i] *= b[i];
fft(lim,a,-1);
for(int i = 0;i <= n + m;++i)
std::cout<<(int)(0.5 + a[i].real() / lim)<<" ";
}
迭代
#include<iostream>
#include<cstdio>
#include<complex>
#define ll long long
#define comp std::complex<double>
#define fft fast_fast_tle
const int N = (1 << 20) + 10 << 1;
const double PI = std::acos(-1.0);
inline ll read(){
ll ans = 0;
char a = getchar();
while(!(a <= '9' && a >= '0'))a = getchar();
while(a <= '9' && a >= '0')
ans = (ans << 3) + (ans << 1) + (a & 15),a = getchar();
return ans;
}
ll n,m,lim,r[N];
comp a[N],b[N];
void fft(comp *a,int type){
for(int i = 0;i < lim;++i)
if(i < r[i])
std::swap(a[i],a[r[i]]);
for(int i = 1;i < lim;i <<= 1){
comp x(cos(PI / i),type * sin(PI / i));
for(int j = 0;j < lim;j += (i << 1)){
comp y(1,0);
for(int k = 0;k < i;++k,y *= x){
comp p = a[j + k],q = y * a[j + k + i];
a[j + k] = p + q;a[j + k + i] = p - q;
}
}
}
}
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();
int l = 0;
for(lim = 1;lim <= n + m;lim <<= 1)++l;
for(int i = 0;i < lim;++i)
r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
fft(a,1),fft(b,1);
for(int i = 0;i <= lim;++i)
a[i] *= b[i];
fft(a,-1);
for(int i = 0;i <= n + m;++i)
std::cout<<(int)(0.5 + a[i].real() / lim)<<" ";
}
(NTT)
NTT
#include<iostream>
#include<cstdio>
#include<complex>
#define ll long long
#define comp std::complex<double>
#define fft fast_fast_tle
#define mod 998244353
#define G 3
#define Gi 332748118 // 1 / 3 在 膜998244353
const int N = (1 << 20) + 10 << 1;
const double PI = std::acos(-1.0);
inline ll read(){
ll ans = 0;
char a = getchar();
while(!(a <= '9' && a >= '0'))a = getchar();
while(a <= '9' && a >= '0')
ans = (ans << 3) + (ans << 1) + (a & 15),a = getchar();
return ans;
}
ll n,m,lim,r[N];
ll a[N],b[N];
inline ll pow(ll a,ll b){
ll ans = 1;
while(b){
if(b & 1)ans = (ans * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return ans;
}
void ntt(ll *a,int type){
for(int i = 0;i < lim;++i)
if(i < r[i])
std::swap(a[i],a[r[i]]);
for(int i = 1;i < lim;i <<= 1){
ll x = pow(type == 1 ? G : Gi,1ll * (mod - 1) / (i << 1));
for(int j = 0;j < lim;j += (i << 1)){
ll y = 1;
for(int k = 0;k < i;++k,y = (y * x) % mod){
ll p = a[j + k] % mod,q = y * a[j + k + i] % mod;
a[j + k] = (p + q + mod) % mod ;a[j + k + i] = (p - q + mod) % mod;
}
}
}
}
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();
int l = 0;
for(lim = 1;lim <= n + m;lim <<= 1)++l;
for(int i = 0;i < lim;++i)
r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
fft(a,1),fft(b,1);
for(int i = 0;i <= lim;++i)
a[i] *= b[i];
fft(a,-1);
for(int i = 0;i <= n + m;++i)
std::cout<<(a[i] * pow(lim,mod - 2) + mod) % mod<<" ";
}