structComplex { double x, y; inline Complex operator+(const Complex sec) const { return Complex{x: x + sec.x, y: y + sec.y}; } inline Complex operator-(const Complex sec) const { return Complex{x: x - sec.x, y: y - sec.y}; } inline Complex operator*(const Complex sec) const { return Complex{x: x * sec.x - y * sec.y, y: x * sec.y + y * sec.x}; } }; Complex Zero = Complex{x: 0, y: 0}, One = Complex{x: 1, y: 0};
int swp[MAXN + 10]; voidEvaSwp(int n){ int mxdeg = n >> 1; for (int i = 1; i < n; ++i) { swp[i] = (swp[i >> 1] >> 1) + ((i & 1) ? mxdeg : 0); } } voidSwp(int n, Complex *a){ for (int i = 0; i < n; ++i) { if (swp[i] > i) { swap(a[i], a[swp[i]]); } } } voidFFT(int n, Complex *a, int getinv){ Swp(n, a); for (int len = 2, halflen = 1; len <= n; len <<= 1, halflen <<= 1) { Complex wlen = Complex{x: cos(twoPI / len), y: sin(twoPI / len)}; for (int l = 0, r = len - 1; r < n; l += len, r += len) { Complex w = One; for (int i = l, j = l + halflen; j <= r; ++i, ++j, w = w * wlen) { Complex u = a[i], v = a[j] * w; a[i] = u + v; a[j] = u - v; } } } if (getinv == -1) { reverse(a + 1, a + n); for (int i = 0; i < n; ++i) { a[i].x /= n; } } }