题意:给出 个数 ,定义 ,令 ,求
设
,分开求
设
,并规定
,那么
,FFT求卷积即可
如果设
即把
翻转,那么
,FFT求卷积即可
#include <cstdio>
#include <cmath>
#include <algorithm>
const int maxn = 1e5 + 207;
const double pi = acos(-1.0);
struct Complex {
double a, b;
Complex(double x, double y) : a(x), b(y) {}
Complex() : Complex(0.0, 0.0) {}
};
inline Complex operator+(const Complex &lhs, const Complex &rhs) {
return Complex(lhs.a + rhs.a, lhs.b + rhs.b);
}
inline Complex operator-(const Complex &lhs, const Complex &rhs) {
return Complex(lhs.a - rhs.a, lhs.b - rhs.b);
}
inline Complex operator*(const Complex &lhs, const Complex &rhs) {
return Complex(lhs.a * rhs.a - lhs.b * rhs.b, lhs.a * rhs.b + lhs.b * rhs.a);
}
int r[maxn << 2], lim, l, n;
Complex a[maxn << 2], b[maxn << 2], c[maxn << 2];
inline void fft(Complex *A, int tp) {
for (int i = 0; i < lim; ++i)
if (i < r[i]) std::swap(A[i], A[r[i]]);
for (int mid = 1; mid < lim; mid <<= 1) {
Complex wn = Complex(cos(pi / mid), tp * sin(pi / mid));
for (int j = 0; j < lim; j += mid << 1) {
Complex w = Complex(1, 0);
for (int k = 0; k < mid; ++k, w = w * wn) {
Complex x = A[j + k], y = w * A[j + k + mid];
A[j + k] = x + y;
A[j + k + mid] = x - y;
}
}
}
if (tp == -1) {
for (int i = 0; i < lim; ++i)
A[i] = Complex(A[i].a / lim, 0);
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%lf", &a[i].a);
b[n - i].a = a[i].a;
}
for (int i = 1; i <= n; ++i)
c[i].a = 1.0 / i / i;
for (lim = 1; lim <= n << 1; 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); fft(c, 1);
for (int i = 0; i <= lim; ++i)
a[i] = a[i] * c[i], b[i] = b[i] * c[i];
fft(a, -1); fft(b, -1);
for (int i = 1; i <= n; ++i)
printf("%.5lf\n", a[i].a - b[n - i].a);
return 0;
}