[luogu P3338] [ZJOI2014]力

题目大意

给 出 n 个 数 q i , 给 出 F j 定 义 如 下 : 给出n个数qi,给出F_{j}定义如下: nqi,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(ij)2qiqji>j(ij)2qiqj
令 E i = F i q i 求 E i 令E_i=\frac{F_i}{q_i}求E_i Ei=qiFiEi

题解

先把式子化简一下
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(ij)2qji>j(ij)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<jfigjii>jfigij
       = ∑ 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=0j1figjii=j+1nfigij
左边显然是卷积的形式,现在来看右边
f i ′ = f n − i + 1 f'_i =f_{n-i+1} fi=fni+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+1nfigij=i=0njfig(nj)i
设 t = n − j 设t=n-j t=nj
∑ i = 0 t f i ′ g t − i \sum\limits_{i=0}^{t}{f'_ig_{t-i}} i=0tfigti
显然也是卷积的形式然后直接上法法踢 f f t fft fft就行了
代码:

#include
#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;
}

你可能感兴趣的:(FFT)