[luogu P3338] [ZJOI2014]力
题目大意
给
出
n
个
数
q
i
,
给
出
F
j
定
义
如
下
:
给出n个数qi,给出F_{j}定义如下:
给出n个数qi,给出Fj定义如下:
F
i
=
∑
i
<
j
q
i
q
j
(
i
−
j
)
2
−
∑
i
>
j
q
i
q
j
(
i
−
j
)
2
F_{i}=\sum_{i<j}{\frac{q_iq_j}{(i-j)^2}}-\sum_{i>j}{\frac{q_iq_j}{(i-j)^2}}
Fi=∑i<j(i−j)2qiqj−∑i>j(i−j)2qiqj
令
E
i
=
F
i
q
i
求
E
i
令E_i=\frac{F_i}{q_i}求E_i
令Ei=qiFi求Ei
题解
先把式子化简一下
E
i
=
∑
i
<
j
q
j
(
i
−
j
)
2
−
∑
i
>
j
q
j
(
i
−
j
)
2
E_{i}=\sum_{i<j}{\frac{q_j}{(i-j)^2}}-\sum_{i>j}{\frac{q_j}{(i-j)^2}}
Ei=∑i<j(i−j)2qj−∑i>j(i−j)2qj
令
F
i
=
q
i
g
i
=
1
i
2
令F_i=q_i g_i=\frac{1}{i^2}
令Fi=qigi=i21
E
i
=
∑
i
<
j
f
i
g
j
−
i
−
∑
i
>
j
f
i
g
i
−
j
\ E_{i}=\sum_{i<j}{f_ig_{j-i}}-\sum_{i>j}{f_ig_{i-j}}
Ei=∑i<jfigj−i−∑i>jfigi−j
=
∑
i
=
0
j
−
1
f
i
g
j
−
i
−
∑
i
=
j
+
1
n
f
i
g
i
−
j
\ \ \ \ \ \ =\sum\limits_{i=0}^{j-1}{f_ig_{j-i}}-\sum\limits_{i=j+1}^{n}{f_ig_{i-j}}
=i=0∑j−1figj−i−i=j+1∑nfigi−j
左边显然是卷积的形式,现在来看右边
令
f
i
′
=
f
n
−
i
+
1
f'_i =f_{n-i+1}
fi′=fn−i+1
∑
i
=
j
+
1
n
f
i
g
i
−
j
=
∑
i
=
0
n
−
j
f
i
′
g
(
n
−
j
)
−
i
\sum\limits_{i=j+1}^{n}{f_ig_{i-j}}=\sum\limits_{i=0}^{n-j}{f'_ig_{(n - j)-i}}
i=j+1∑nfigi−j=i=0∑n−jfi′g(n−j)−i
设
t
=
n
−
j
设t=n-j
设t=n−j
∑
i
=
0
t
f
i
′
g
t
−
i
\sum\limits_{i=0}^{t}{f'_ig_{t-i}}
i=0∑tfi′gt−i
显然也是卷积的形式然后直接上法法踢
f
f
t
fft
fft就行了
代码:
#include<bits/stdc++.h>
#define N 450005
using namespace std;
const double pi = acos(-1.0);
struct complexx{
double x, y;
complexx(double xx = 0, double yy = 0) {x = xx, y = yy;}
}a[N], f[N], g[N], ff[N], gg[N];
double coss[N], sinn[N], q[N];
int rev[N];
complexx operator + (complexx a, complexx b) {return complexx(a.x + b.x, a.y + b.y);}
complexx operator - (complexx a, complexx b) {return complexx(a.x - b.x, a.y - b.y);}
complexx operator * (complexx a, complexx b) {return complexx(a.x * b.x - a.y * b.y, a.y * b.x + a.x * b.y);}
void fft(int len, complexx *a, int o){
for(int i = 0; i <= len; i ++) if(i < rev[i]) swap(a[i], a[rev[i]]);
for(int j = 1; j < len; j <<= 1){
complexx wn = complexx(coss[j], o * sinn[j]);
for(int k = 0; k < len; k += (j << 1)){
complexx w0 = complexx(1, 0);
for(int i = 0; i < j; i ++, w0 = w0 * wn){
complexx X = a[i + k], Y = w0 * a[i + j + k];
a[i + k] = X + Y;
a[i + k + j] = X - Y;
}
}
}
}
void cheng(int n, int m, complexx *a, complexx *b){
int len = 1, l = 0;
for(;len <= n + m; len <<= 1, l ++);
for(int i = 0; i <= len; i ++) rev[i] = (rev[i >> 1] >> 1) | ((i&1) << (l - 1));
for(int i = 1; i <= len; i <<= 1) coss[i] = cos(pi / i), sinn[i] = sin(pi / i);
fft(len, a, 1);
fft(len, b, 1);
for(int i = 0; i <= len; i ++)
a[i] = a[i] * b[i];
fft(len, a, -1);
for(int i = 0; i <= n + m; i ++) a[i].x = a[i].x / len;
}
int n, m;
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%lf", &q[i]), f[i].x = q[i], ff[n - i + 1].x = q[i];
for(int i = 1; i <= n; i ++) gg[i].x = g[i].x = 1.0 / i / i;
cheng(n, n, f, g);
cheng(n, n, ff, gg);
for(int i = 1; i <= n; i ++) printf("%.3f\n", f[i].x - ff[n - i + 1].x);
return 0;
}