题意:给定 ({q_i}),求
[E_i = sum_{i<j}{frac{q_j}{(j-i)^2}} - sum_{i>j}{frac{q_j}{(j-i)^2}}
]
Solution: 我们令
[p_i = frac{1}{(j-i)^2}
]
那么很容易将(E_i)处理为卷积形式
[E_i = sum_{i<j}{p_{j-i}q_j} - sum_{i>j}{p_{i-j}q_j}
]
可以暴力地把两边分开处理,不需要的区域直接置为(0),对于下标出现负数的暴力加上一个(n)即可。最终我们将答案转化为
[E_i = sum_{i<j}{p_{j-i}q'_{n-i-1}} - sum_{i>j}{p_{i-j}q_j}
]
其中 (q') 是(q)的翻转序列,即 (q'_i=q_{n-i-1}) 。
之所以在这个算式里仍然需要考虑负数下标,是因为我们在做卷积的时候无法对 (i<j) 和 (i>j) 这样的约束进行满足,因此我们将 (p) 序列整体平移一个 (n) 即可。
poly p,q;
int main() {
int n;
scanf("%d",&n);
q.read(n-1);
p.c.resize(n+n);
for(int i=0;i<=n;i++) p.c[i]=0;
for(int i=1;i<n;i++) p.c[n+i]=1.0/((double)i*(double)i);
poly A=p*q;
reverse(q.c.begin(),q.c.end());
poly B=p*q;
for(int i=0;i<n;i++) {
printf("%.3lf
",-B.c[2*n-i-1]+A.c[n+i]);
}
}
当然很容易发现这样做毫无必要。既然我们已经对下标为负数的情况做了处理,不妨顺便把它利用上。
poly p,q;
int main() {
int n;
scanf("%d",&n);
q.read(n-1);
p.c.resize(n+n);
for(int i=1;i<n;i++)
p.c[n+i]=1.0/((double)i*(double)i),
p.c[n-i]=-1.0/((double)i*(double)i);
poly A=p*q;
for(int i=0;i<n;i++) {
printf("%.3lf
",A.c[n+i]);
}
}