[ZJOI3527][Zjoi2014]力
[ZJOI3527][Zjoi2014]力
试题描述
给出n个数qi,给出Fj的定义如下:
令Ei=Fi/qi。试求Ei。
输入
包含一个整数n,接下来n行每行输入一个数,第i行表示qi。
输出
有n行,第i行输出Ei。与标准答案误差不超过1e-2即可。
输入示例
5 4006373.885184 15375036.435759 1717456.469144 8514941.004912 1410681.345880
输出示例
-16838672.693 3439.793 7509018.566 4595686.886 10903040.872
数据规模及约定
对于30%的数据,n≤1000。
对于50%的数据,n≤60000。
对于100%的数据,n≤100000,0<qi<1000000000。
题解
把 qj 除掉得到
容易发现这是个卷积。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> using namespace std; #define maxn 1200010 const double pi = acos(-1.0); struct Complex { double a, b; Complex operator + (const Complex& t) { Complex ans; ans.a = a + t.a; ans.b = b + t.b; return ans; } Complex operator - (const Complex& t) { Complex ans; ans.a = a - t.a; ans.b = b - t.b; return ans; } Complex operator * (const Complex& t) { Complex ans; ans.a = a * t.a - b * t.b; ans.b = a * t.b + b * t.a; return ans; } Complex operator *= (const Complex& t) { *this = *this * t; return *this; } } q[maxn], t[maxn]; int Ord[maxn]; void FFT(Complex* x, int n, int tp) { for(int i = 0; i < n; i++) if(i < Ord[i]) swap(x[i], x[Ord[i]]); for(int i = 1; i < n; i <<= 1) { Complex wn, w; wn.a = cos(pi / i); wn.b = (double)tp * sin(pi / i); for(int j = 0; j < n; j += (i << 1)) { w.a = 1.0; w.b = 0.0; for(int k = 0; k < i; k++) { Complex t1 = x[j+k], t2 = w * x[j+k+i]; x[j+k] = t1 + t2; x[j+k+i] = t1 - t2; w *= wn; } } } return ; } int main() { int n; scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%lf", &q[i].a), q[i].b = 0.0; t[0].a = t[n].a = t[0].b = t[n].b = 0.0; for(int i = 1; i < n; i++) t[i].a = -1.0 / (n - i) / (n - i), t[i+n].a = 1.0 / i / i, t[i].b = t[i+n].b = 0.0; // for(int i = 0; i < n; i++) printf("%.5lf %.5lf\n", t[i].a, t[i+n].a); int m = n * 3, L = 0; for(n = 1; n <= m; n <<= 1) L++; for(int i = 0; i < n; i++) Ord[i] = (Ord[i>>1] >> 1) | ((i & 1) << L - 1); FFT(q, n, 1); FFT(t, n, 1); for(int i = 0; i <= n; i++) q[i] *= t[i]; FFT(q, n, -1); for(int i = m / 3; i < (m / 3 << 1); i++) printf("%.6lf\n", q[i].a / (double)n); return 0; }