LuoguP3338 [ZJOI2014]力

题目描述

给出n个数qi,给出Fj的定义如下:

\[F_j = \sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{i>j}\frac{q_i q_j}{(i-j)^2 } \]

\(E_i=\frac{F_i}{q_i}\),求\(E_i\).

输入输出格式

输入格式:

第一行一个整数n。

接下来n行每行输入一个数,第i行表示qi。

输出格式:

n行,第i行输出Ei。

与标准答案误差不超过1e-2即可。

输入输出样例

输入样例#1:

5
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880

输出样例#1:

-16838672.693
3439.793
7509018.566
4595686.886
10903040.872

说明

对于30%的数据,n≤1000。

对于50%的数据,n≤60000。

对于100%的数据,n≤100000,0<qi<1000000000。

[spj 0.01]

题解

https://www.cnblogs.com/iwtwiioi/p/4126284.html
看这个题解吧。。

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <algorithm>
inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}
inline void swap(double &a, double &b){double tmp = a;a = b;b = tmp;}
inline void read(int &x)
{
    x = 0;char ch = getchar(), c = ch;
    while(ch < '0' || ch > '9') c = ch, ch = getchar();
    while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    if(c == '-') x = -x;
}
const int MAXN = 1 << 18;
const double PI = acos(-1);
struct Complex 
{
    double real, imag;
    Complex(double _real, double _imag){real = _real, imag = _imag;}
    Complex(){real = imag = 0;}
    Complex operator+(const Complex &x) const {return Complex(real + x.real, imag + x.imag);}
	Complex operator-(const Complex &x) const {return Complex(real - x.real, imag - x.imag);}
    Complex operator*(const Complex &x) const {return Complex(real * x.real - imag * x.imag, real * x.imag + imag * x.real);}
    Complex& operator*=(const Complex &x) {return *this = (*this) * x;}
};
int n, m, tn, len, rev[MAXN], tmp;
Complex a[MAXN], b[MAXN], c[MAXN];
double q[MAXN];
void fft(Complex *arr, int f) 
{
	for(int i = 0; i < n; i++) if(i < rev[i]) std::swap(arr[i], arr[rev[i]]);
    for(int i = 1; i < n; i <<= 1) 
	{
    	Complex wn(cos(PI / i), f * sin(PI / i));
        for(int j = 0; j < n; j += i << 1) 
		{
            Complex w(1, 0);
            for(int k = 0; k < i; k++) 
			{
            	Complex x = arr[j + k], y = w * arr[j + k + i];
            	arr[j + k] = x + y;
                arr[j + k + i] = x - y;
                w *= wn;
            }
        }
    }
    if(f == -1) for(int i = 0;i < n;++ i) arr[i].real /= n;
}
int main() 
{
	read(n), -- n, tn = n;
	for(int i = 0;i <= tn;++ i) scanf("%lf", &q[i]);
	
	for(int i = 0;i <= tn;++ i) a[i].real = q[i], c[i].real = q[tn - i];
	for(int i = 1;i <= tn;++ i) b[i].real = (double)1.0/i/i; 
	m = tn + tn;
	for(n = 1;n <= m;n <<= 1) ++ len;
	
	for(int i = 0; i < n; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1));
	fft(a, 1), fft(b, 1), fft(c, 1);
	for(int i = 0;i <= n;++ i) a[i] *= b[i], c[i] *= b[i];
	fft(a, -1), fft(c, -1);
	
	for(int i = 0;i <= tn;++ i)
		printf("%.3lf\n", a[i].real - c[tn - i].real);
	return 0;
}
posted @ 2018-05-10 10:27  嘒彼小星  阅读(221)  评论(0编辑  收藏  举报