[Zjoi2014] 力

3527: [Zjoi2014]力

Time Limit: 30 Sec  Memory Limit: 256 MBSec  Special Judge
Submit: 3706  Solved: 2304
[Submit][Status][Discuss]

Description

给出n个数qi,给出Fj的定义如下:
令Ei=Fi/qi,求Ei.
 

Input

第一行一个整数n。
接下来n行每行输入一个数,第i行表示qi。
n≤100000,0<qi<1000000000
 
 

Output

 n行,第i行输出Ei。与标准答案误差不超过1e-2即可。

Sample Input

5
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880

Sample Output

-16838672.693
3439.793
7509018.566
4595686.886
10903040.872
 
卷积 注意n*n爆int
#include <bits/stdc++.h>
using namespace std;
const int maxn = 524288;
struct comp{
    double x, y;
    comp(double _x = 0, double _y = 0){
        x = _x;
        y = _y;
    }
    friend comp operator * (const comp &a, const comp &b){
        return comp(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
    }
    friend comp operator + (const comp &a, const comp &b){
        return comp(a.x + b.x, a.y + b.y);
    }
    friend comp operator - (const comp &a, const comp &b){
        return comp(a.x - b.x, a.y - b.y);
    }
}f[maxn], g[maxn];
int rev[maxn];
void dft(comp A[], int len, int kind){
    for(int i = 0; i < len; i++){
        if(i < rev[i]){
            swap(A[i], A[rev[i]]);
        }
    }
    for(int i = 1; i < len; i <<= 1){
        comp wn(cos(acos(-1.0) / i), kind * sin(acos(-1.0) / i));
        for(int j = 0; j < len; j += (i << 1)){
            comp tmp(1, 0);
            for(int k = 0; k < i; k++){
                comp s = A[j + k], t = tmp * A[i + j + k];
                A[j + k] = s + t;
                A[i + j + k] = s - t;
                tmp = tmp * wn;
            }
        }
    }
    if(kind == -1) for(int i = 0; i < len; i++) A[i].x /= len;
}
double q[maxn], e[maxn] = {0};
int main(){
    int n, len, L = 0;
    scanf("%d", &n); 
    q[0] = g[0].x = 0;
    for(int i = 1; i <= n; i++) scanf("%lf", q + i);
    for(int i = 1; i <= n; i++) f[i].x = 1.0 / i / i;
    n++;
    for(len = 1; len < n + n - 1; len <<= 1, L++);
    for(int i = 0; i < len; i++){
        rev[i] = rev[i >> 1] >> 1 | (i & 1) << L - 1;
    }
    for(int i = 0; i < n; i++) g[i].x = q[i];
    dft(f, len, 1); dft(g, len, 1);
    for(int i = 0; i < len; i++) g[i] = f[i] * g[i];
    dft(g, len, -1);
    for(int i = 1; i < n; i++) e[i] += g[i].x;
    for(int i = 0; i < len; i++) g[i] = comp();
    for(int i = 1; i < n; i++) g[i].x = q[n - i];
    dft(g, len, 1);
    for(int i = 0; i < len; i++) g[i] = f[i] * g[i];
    dft(g, len, -1);
    for(int i = 1; i < n; i++) e[i] -= g[n - i].x;
    for(int i = 1; i < n; i++)
        printf("%.3lf\n", e[i]);
    return 0;
}

 

posted @ 2019-10-29 17:21  Elder_Giang  阅读(98)  评论(0编辑  收藏  举报