FFT;把b数组倒过来就好看了
#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<(n);i++)
using namespace std;
typedef double db;
const int maxn = (1 << 20) + 5;
const db pi = acos(-1.0);
struct virt {
db r, i;
virt(db r = 0.0, db i = 0.0): r(r), i(i) {}
};
virt operator+(virt a, virt b) {
return virt(a.r + b.r, a.i + b.i);
}
virt operator-(virt a, virt b) {
return virt(a.r - b.r, a.i - b.i);
}
virt operator*(virt a, virt b) {
return virt(a.r * b.r - a.i * b.i, a.i * b.r + a.r * b.i);
}
virt a[maxn], b[maxn];
int n, m, L = 0, rev[maxn], cn;
void fft(virt* x, int op) {
rep(i, 1, n)if(rev[i] > i)swap(x[rev[i]], x[i]);
for(int h = 2; h <= n; h <<= 1) {
virt wn = virt(cos(op * 2 * pi / h), sin(op * 2 * pi / h));
for(int j = 0; j < n; j += h) {
virt w = virt(1.0, 0.0);
for(int k = j; k < j + h / 2; k++) {
virt p = x[k];
virt q = w * x[k + h / 2];
x[k] = p + q;
x[k + h / 2] = p - q;
w = w * wn;
}
}
}
if(op == -1)rep(i, 0, n)x[i].r /= n;
}
int main() {
//freopen("in.in", "r", stdin);
scanf("%d", &n);
cn = n;
rep(i, 0, n) {
scanf("%lf%lf", &a[i].r, &b[n - i - 1].r);
a[i].i = b[n - 1 - i].i = 0.0;
}
m = n << 1;
for(n = 1; n <= m; n <<= 1)L++;
rep(i, 0, n)rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (L - 1));
fft(a, 1);
fft(b, 1);
rep(i, 0, n + 1)a[i] = a[i] * b[i];
fft(a, -1);
rep(i, cn - 1, 2 * cn - 1)printf("%d\n", (int)(a[i].r + 0.1));
return 0;
}
115

被折叠的 条评论
为什么被折叠?



