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