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

 

posted @ 2016-08-02 09:00  xjr01  阅读(256)  评论(0编辑  收藏  举报