【BZOJ 2194】快速傅立叶之二
随便代换一下把它变成多项式乘法,及$C[T]=\sum_{i=0}^{T}A[i]×B[T-i]$这种形式,然后FFT求一下就可以啦
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define read(x) x=getint() using namespace std; const int N = 400003; const double Pi = acos(- 1.0); int getint() { int k = 0, fh = 1; char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if (c == '-') fh = -1; for(; c >= '0' && c <= '9'; c = getchar()) k = k * 10 + c - '0'; return k * fh; } struct cp { double r, i; cp (double _r = 0.0, double _i = 0.0) : r(_r), i(_i) {} cp operator + (const cp &x) {return cp(r + x.r, i + x.i);} cp operator - (const cp &x) {return cp(r - x.r, i - x.i);} cp operator * (const cp &x) {return cp(r * x.r - i * x.i, r * x.i + i * x.r);} }; cp A[N], u, t; int rev[N]; void DFT(cp *a, int n, int flag) { for(int i = 0; i < n; ++i) A[rev[i]] = a[i]; for(int i = 0; i < n; ++i) a[i] = A[i]; for(int m = 2; m <= n; m <<= 1) { cp wn(cos(2.0 * Pi / m * flag), sin(2.0 * Pi / m * flag)); int mid = m >> 1; for(int i = 0; i < n; i += m) { cp w(1.0); for(int j = 0; j < mid; ++j) { u = a[i + j], t = a[i + j + mid] * w; a[i + j] = u + t; a[i + j + mid] = u - t; w = w * wn; } } } if (flag == -1) for(int i = 0; i < n; ++i) a[i].r /= n; } void init(int &n) { int k = 1, ret, L = 0; for(; k < n; k <<= 1, ++L); n = k; for(int i = 0; i < n; ++i) { k = i; ret = 0; for(int j = 0; j < L; ++j) ret <<= 1, ret |= k & 1, k >>= 1; rev[i] = ret; } } void FFT(int *a, int *b, int *c, int la, int lb) { static cp x[N], y[N]; int len = la + lb - 1; init(len); for(int i = 0; i < len; ++i) x[i].r = a[i], x[i].i = 0; for(int i = 0; i < len; ++i) y[i].r = b[i], y[i].i = 0; DFT(x, len, 1); DFT(y, len, 1); for(int i = 0; i < len; ++i) x[i] = x[i] * y[i]; DFT(x, len, -1); for(int i = 0; i < len; ++i) c[i] = (int) (x[i].r + 0.5); } int x[N], y[N], a[N], n; int main() { read(n); for(int i = 0; i < n; ++i) read(x[i]), read(y[i]); for(int i = 0; i < n; ++i) a[i] = x[n - i - 1]; FFT(y, a, x, n, n); for(int i = 0; i < n; ++i) a[i] = x[n - i - 1]; for(int i = 0; i < n; ++i) printf("%d\n", a[i]); return 0; }
233
NOI 2017 Bless All