[洛谷P3338][ZJOI2014]力

题目大意:给你$n$个数$q_i$,令$F_j=\sum\limits_{i<j}\dfrac{q_iq_j}{(i−j)^2}−\sum\limits_{i>j}\dfrac{q_iq_j}{(i−j)^2}$,令$E_i=\dfrac{F_i}{q_i}$。求$E_i$

题解:

$$
E_j=\sum\limits_{i=1}^{j-1}\dfrac{q_i}{(i−j)^2}−\sum\limits_{i=j+1}^n\dfrac{q_i}{(i−j)^2}\\
令x_j=\sum\limits_{i=1}^{j-1}\dfrac{q_i}{(i-j)^2},y_j=\sum\limits_{i=j+1}^n\dfrac{q_i}{(i−j)^2}\\
E_i=x_i-y_i\\
令f_i=i^{-2}\\
x=f*q,y^R=f*q^R\\
FFT即可
$$

卡点:

 

C++ Code:

#include <cstdio>
#include <algorithm>
#include <cmath>
#define maxn 262144
const double Pi = acos(-1);

struct complex {
	double r, i;
	inline complex(double __r = 0, double __i = 0) {r = __r, i = __i;}
	inline complex operator + (const complex &rhs) const {return (complex) {r + rhs.r, i + rhs.i};}
	inline complex operator - (const complex &rhs) const {return (complex) {r - rhs.r, i - rhs.i};}
	inline complex operator * (const complex &rhs) const {return (complex) {r * rhs.r - i * rhs.i, r * rhs.i + i * rhs.r};}
	inline complex operator / (const int &x) const {return (complex) {r / x, i / x};}
} q[maxn], qR[maxn], a[maxn], A[maxn], B[maxn];
int lim, rev[maxn], s;
inline void init(int n) {
	lim = 1, s = -1; while (lim < n) lim <<= 1, s++;
	for (int i = 0; i < lim; i++) rev[i] = rev[i >> 1] >> 1 | (i & 1) << s;
}
inline void FFT(complex *A, int op = 1) {
	for (int i = 0; i < lim; i++) if (i < rev[i]) std::swap(A[i], A[rev[i]]);
	for (int mid = 1; mid < lim; mid <<= 1) {
		complex Wn(cos(Pi / mid), op * sin(Pi / mid));
		for (int i = 0; i < lim; i += mid << 1) {
			complex W(1, 0);
			for (int j = 0; j < mid; j++, W = W * Wn) {
				complex X = A[i + j], Y = A[i + j + mid] * W;
				A[i + j] = X + Y, A[i + j + mid] = X - Y;
			}
		}
	}
	if (op == -1) for (int i = 0; i < lim; i++) A[i] = A[i] / lim;
}

int n;
int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%lf", &q[i].r);
		qR[n - i - 1].r = q[i].r;
		if (i) a[i].r = 1.0 / i / i;
	}
	init(n << 1);
	FFT(q), FFT(qR), FFT(a);
	for (int i = 0; i < lim; i++) A[i] = q[i] * a[i], B[i] = qR[i] * a[i];
	FFT(A, -1), FFT(B, -1);
	for (int i = 0; i < n; i++) printf("%.3lf\n", A[i].r - B[n - i - 1].r);
	return 0;
}

  

posted @ 2018-10-10 15:10  Memory_of_winter  阅读(175)  评论(0编辑  收藏  举报