BZOJ 3527(FFT模板)

来源:互联网 发布:java初级教程 编辑:程序博客网 时间:2024/06/15 03:00

3527: [Zjoi2014]力

Time Limit: 30 Sec  Memory Limit: 256 MBSec  Special Judge
Submit: 2308  Solved: 1364
[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

HINT

Source

代码:
#include<bits/stdc++.h>
using namespace std;
const int FFT_MAXN = 1 << 18;
const double pi = acos(-1.0);
struct Complex
{
    double R, I;
    inline Complex(double real = 0.0, double image = 0.0)
    {
        R = real, I = image;
    }
    inline Complex operator + (Complex const &b) const
    {
        return Complex(R + b.R, I + b.I);
    }
    inline Complex operator - (Complex const &b) const
    {
        return Complex(R - b.R, I - b.I);
    }
    inline Complex operator * (Complex const &b) const
    {
        return Complex(R * b.R - I * b.I, I * b.R + R * b.I);
    }
} Wn[FFT_MAXN + 1];
int bitrev[FFT_MAXN];




void Change(Complex a[], int n)
{
    int d = 0;
    while((1 << d)*n != FFT_MAXN)
        d++;
    for(int i = 0; i < n; i++)
        if(i < (bitrev[i] >> d))
            swap(a[i], a[bitrev[i] >> d]);
}
void FFT(Complex P[], int n, int op)
{
    Change(P, n);
    for(int len = 2; len <= n; len <<= 1)
    {
        int m = len >> 1;
        int del = FFT_MAXN / len * op;
        for(int i = 0; i < n; i += len)
        {
            Complex *p = P + i, *q = P + i + m, *w = op == 1 ? Wn : Wn + FFT_MAXN;
            for(int j = 0; j < m; j++, p++, q++, w += del)
            {
                Complex ne = *q * *w;
                *q = *p - ne;
                *p = *p + ne;
            }
        }
    }
    if(op == -1)
        for(int i = 0; i < n; i++)
        {
            P[i].R /= n;
            P[i].I /= n;
        }
}
void FFTInit()
{
    int L = 0;
    while((1 << L) != FFT_MAXN)
        L++;
    bitrev[0] = 0;
    for(int i = 1; i < FFT_MAXN; i++)
        bitrev[i] = bitrev[i >> 1] >> 1 | ((i & 1) << (L - 1));
    for(int i = 0; i <= FFT_MAXN; i++)
        Wn[i] = Complex(cos(2 * pi / FFT_MAXN * i), sin(2 * pi / FFT_MAXN * i));
}
Complex A[FFT_MAXN], B[FFT_MAXN];
double  ans[FFT_MAXN], src[FFT_MAXN];
int main()
{
    FFTInit();
    int cnt;
    cin >> cnt;
    for(int i = 0; i < cnt; ++i) scanf("%lf", &src[i]);
    int l = 1;
    for(; l <= cnt << 1; l <<= 1);
    for(int i = 0; i < cnt; ++i) A[i] = Complex(src[i]);
    for(int i = 1; i < cnt; ++i) B[i] = Complex(1.0 / i / i);
    FFT(A, l, 1), FFT(B, l, 1);
    for(int i = 0; i < l; ++i) A[i] = A[i] * B[i];
    FFT(A, l, -1);
    for(int i = 0; i < cnt; ++i) ans[i] = A[i].R;
    reverse(src, src + cnt);
    memset(A, 0, sizeof(A));
    memset(B, 0, sizeof(B));
    for(int i = 0; i < cnt; ++i) A[i] = Complex(src[i]);
    for(int i = 1; i < cnt; ++i) B[i] = Complex(1.0 / i / i);
    FFT(A, l, 1), FFT(B, l, 1);
    for(int i = 0; i < l; ++i) A[i] = A[i] * B[i];
    FFT(A, l, -1);
    for(int i = 0; i < cnt; ++i) ans[i] -= A[cnt - i - 1].R;
    for(int i = 0; i < cnt; ++i) printf("%lf\n", ans[i]);
    return 0;
}


原创粉丝点击