链接:
题目大意:
给出 (n) 个数 (q_1,q_2,cdots,q_n),定义:
[F_j=sum_{i = 1}^{j - 1} frac{q_i cdot q_j}{(i - j)^2}-sum_{i = j + 1}^{n} frac{q_i cdot q_j}{(i - j)^2}\
E_i=frac{F_i}{q_i}]
对 (1leq ileq n),求 (E_i) 的值。
正文:
将 (F_i) 代入 (E_i) 得到:
[egin{aligned}E_i&=sum_{j = 1}^{i - 1} frac{q_j}{(i - j)^2}-sum_{j = i + 1}^{n} frac{q_j}{(i - j)^2}\
&=sum_{j = 1}^{i} frac{q_j}{(i - j)^2}-sum_{j = i}^{n} frac{q_j}{(i - j)^2}end{aligned}]
设 (f_i=q_i,g_i=frac{1}{i^2}),那么:
[E_i=sum_{j = 1}^{i} f_j cdot g_{i-j} -sum_{j = i}^{n} f_j cdot g_{j-i}
]
左边的和式已经在卷了,想办法让右边的和式也转化成卷积的形式。
可以将它转化成这样:
[sum_{j = 0}^{n-i} f_{i+j} cdot g_{j}
]
设 (f'_i=f_{n-i}) 得到:
[sum_{j = 0}^{n-i} f'_{n-(i+j)} cdot g_{j}=sum_{j = 0}^{n-i} f'_{n-i-j} cdot g_{j}
]
定义 (t=n-i):
[sum_{j = 0}^{t} f'_{t-j} cdot g_{j}
]
这个和式也是卷积形式了,FFT 求解了。
const int N = 200010;
const double PI = acos(-1.0);
struct Complex
{
double x, y;
Complex (double ix, double iy) {x = ix, y = iy;}
Complex () {x = y = 0;}
Complex operator + (Complex &b)
{
return Complex(x + b.x, y + b.y);
}
Complex operator - (Complex &b)
{
return Complex(x - b.x, y - b.y);
}
Complex operator * (Complex &b)
{
return Complex(x * b.x - y * b.y, x * b.y + y * b.x);
}
}a[N << 1], b[N << 1], c[N << 1];
int n, m;
int tr[N << 1];
void FFT (Complex *f, bool isDFT)
{
for (int i = 0; i <= n; i++)
if (i < tr[i]) swap (f[i], f[tr[i]]);
for (int p = 2; p <= n; p <<= 1)
{
int len = p >> 1;
Complex omega(cos(2 * PI / p), sin(2 * PI / p));
if (!isDFT) omega.y *= -1;
for (int k = 0; k < n; k += p)
{
Complex tmp(1, 0);
for (int i = k; i < k + len; i ++)
{
Complex y = tmp * f[i + len];
f[i + len] = f[i] - y;
f[i] = f[i] + y;
tmp = tmp * omega;
}
}
}
if(!isDFT) for (int i = 0; i < n; i++) f[i].x /= n;
}
int main()
{
scanf ("%d", &n);
for (int i = 1; i <= n; i++)
scanf ("%lf", &a[i].x),
c[n - i].x = a[i].x, b[i].x = (double) (1.0 / i / i);
for (m = n, n = 1; n <= (m << 1); n <<= 1);
for (int i = 0; i < n; i++)
tr[i] = (tr[i >> 1] >> 1) | (i & 1? n >> 1: 0);
FFT(a, 1), FFT(b, 1), FFT(c, 1);
for (int i = 0; i < n; i++) a[i] = a[i] * b[i], c[i] = c[i] * b[i];
FFT(a, 0), FFT(c, 0);
for (int i = 1; i <= m; i++)
printf ("%.3lf
", a[i].x - c[m - i].x);
return 0;
}