FFT模板
#include<iostream> #include<algorithm> #include<cmath> #include<cstdio> #include<queue> #include<cstring> #include<ctime> #include<string> #include<vector> #include<map> #include<list> #include<set> #include<stack> #include<bitset> #include<unordered_map> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll, ll> pii; typedef pair<ll, ll> pll; const ll N = 3e6 + 5; const ll mod = 998244353; const ll INF = 0x3f3f3f3f; const ll INF64 = 0x3f3f3f3f3f3f3f3f; const double gold = (1 + sqrt(5)) / 2.0; const double PI = acos(-1); const double eps = 1e-8; ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); } ll pow(ll x, ll y, ll mod) { ll ans = 1; while (y) { if (y & 1)ans = (ans * x) % mod; x = (x * x) % mod; y >>= 1; }return ans; } ll pow(ll x, ll y) { ll ans = 1; while (y) { if (y & 1)ans = (ans * x) % mod; x = (x * x) % mod; y >>= 1; }return ans; } ll inv(ll x) { return pow(x, mod - 2); } //使用时记得开大空间2倍以上,开3倍空间 struct complex{ double x, y; complex(double xx = 0, double yy = 0) { x = xx, y = yy; } }; complex operator + (complex a, complex b) { return complex(a.x + b.x, a.y + b.y); } complex operator - (complex a, complex b) { return complex(a.x - b.x, a.y - b.y); } complex operator * (complex a, complex b) { return complex(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x); } int l, r[N]; int limit = 1; //type 为1则是DFT,为-1则是IDFT void FFT(complex *A, int type) { for (int i = 0; i < limit; i++) if (i < r[i]) swap(A[i], A[r[i]]); for (int mid = 1; mid < limit; mid <<= 1){ complex Wn(cos(PI / mid), type*sin(PI / mid)); for (int R = mid << 1, j = 0; j < limit; j += R){ complex w(1, 0); for (int k = 0; k < mid; k++, w = w * Wn){ complex x = A[j + k], y = w * A[j + mid + k]; A[j + k] = x + y; A[j + mid + k] = x - y; } } } } complex A[N], B[N]; int CANS[N]; //n和m并不是个数,而是次数,即个数-1 //最后的CANS即为答案 void Convolution(int *a,int n,int *b,int m) { //赋值 for (int i = 0; i <= n; i++)A[i].x = a[i]; for (int i = 0; i <= m; i++)B[i].x = b[i]; //补齐为2的k次方 while (limit <= n + m) limit <<= 1, l++; for (int i = 0; i < limit; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1)); //DFT FFT(A, 1); FFT(B, 1); //计算 for (int i = 0; i < limit; i++) A[i] = A[i] * B[i]; //IDFT FFT(A, -1); //按照我们推倒的公式,这里还要除以n for (int i = 0; i <= n+m; i++)CANS[i]= (int)(A[i].x / limit + 0.5); } int a[N], b[N]; int main() { int n, m,p; scanf("%d%d%d", &n, &m,&p); for (int i = 0; i <= n; i++) scanf("%d", a + i); for (int i = 0; i <= m; i++) scanf("%d", b + i); Convolution(a, n, b, m); for (int i = 0; i <= n + m; i++) printf("%d ",CANS[i]%p); printf("\n"); }