LOJ2200 力

如果把原式化为卷积形式,就可以用\(FFT\)优化。   \(E_j=\frac{F_j}{q_j}=\sum\limits_{i=1}^{j-1}\frac{q_i}{(i-j)^2}-\sum\limits_{i=j+1}^{n}\frac{q_i}{(i-j)^2}\)
\(E_j=\frac{F_j}{q_j}=\sum\limits_{i=0}^{j}\frac{q_i}{(i-j)^2}-\sum\limits_{i=j}^{n}\frac{q_i}{(i-j)^2}\)\(f(i)=q_i,g(i)=\frac{1}{i^2}\)
则原式, \(E_j=\sum\limits_{i=0}^{j}f(i)g(j-i)-\sum\limits_{i=0}^{n-j}f(i+j)g(i)\)   左边已经是卷积形式了,考虑右边。   把右边拆开,\(f(j)g(0)+f(j+1)g(1)+...+f(j+(n-j))g(n-j)\).
做一下翻转\(f(j)=f'(n-j)\).
\(\sum\limits_{i=j}^{n}f(i)g(i-j)=\sum\limits_{i=0}^{n-j}f'(n-(j+i))g(i)\)
然后右边也是卷积形式了。   设\(A(x)=\sum\limits_{i=0}^{n}f(i)\),\(B(x)=\sum\limits_{i=0}^{n}f'(i)\),\(C(x)=\sum\limits_{i=0}^{n}g(i)\).
\(E_j\)等于\(A(x)\cdot C(x)\)的第\(j\)项系数和\(B(x)\cdot C(x)\)的第\(n-j\)项系数之差。  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <bits/stdc++.h>
using namespace std;

typedef complex<double> cp;
const int N = 8e5 + 5;
const double pi = acos(-1.0);
int n, l, len, rev[N];
cp a[N], b[N], c[N];

void fft(cp *a, int n, int inv) {
for (int i = 1; i < n; i++) if (i < rev[i]) swap(a[i], a[rev[i]]);
for (int k = 1; k < n; k <<= 1) {
cp wn(cos(pi / k), inv * sin(pi / k));
for (int i = 0; i < n; i += k * 2) {
cp w(1, 0);
for (int j = 0; j < k; j++, w *= wn) {
cp x = a[i + j], y = w * a[i + j + k];
a[i + j] = x + y, a[i + j + k] = x - y;
}
}
}
if (inv < 0) for (int i = 0; i < n; i++) a[i] /= n;
}

int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lf", &a[i]);
b[n - i] = a[i];
c[i] = 1.0 / i / i;
}
len = 1;
while (len <= n * 2) len <<= 1, l++;
for (int i = 0; i < len; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1));
fft(a, len, 1), fft(b, len, 1), fft(c, len, 1);
for (int i = 0; i < len; i++) {
a[i] = a[i] * c[i];
b[i] = b[i] * c[i];
}
fft(a, len, -1); fft(b, len, -1);
for (int i = 1; i <= n; i++) {
printf("%lf\n", a[i].real() - b[n - i].real());
}
return 0;
}