BZOJ 3527 ZJOI 2014 力 FFT

题目大意

定义

求E[i] = F[i] / q[i]

思路

经过推导发现最后形成了卷积的形式,之后直接套用FFT就行了。

注意卷积卷起来之后占用的是2倍的空间。。

CODE

#define _CRT_SECURE_NO_WARNINGS

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000010
using namespace std;
const double PI = acos(-1.0);

struct Complex{
    double x,y;

    Complex(double _,double __ = .0):x(_),y(__) {}
    Complex() {}
    void operator +=(const Complex &a) {
        x += a.x,y += a.y;
    }
    void operator -=(const Complex &a) {
        x -= a.x,y -= a.y;
    }
    void operator /=(double a) {
        x /= a,y /= a;
    }
    void operator *=(const Complex &a) {
        double _ = x * a.x - y * a.y,__ = x * a.y + y * a.x;
        x = _,y = __;
    }
    Complex operator +(const Complex &a)const {
        return Complex(x + a.x,y + a.y);
    }
    Complex operator -(const Complex &a)const {
        return Complex(x - a.x,y - a.y);
    }
    Complex operator /(double a)const {
        return Complex(x / a,y / a);
    }
    Complex operator *(const Complex &a)const {
        return Complex(x * a.x - y * a.y,x * a.y + y * a.x);
    }
};

inline void FFT(Complex A[],int cnt,int flag)
{
    for(int i = 0,k = 0; i < cnt; ++i) {
        if(i < k)    swap(A[i],A[k]);
        for(int j = cnt >> 1; (k ^= j) < j; j >>= 1);
    }
    Complex w,wn,t;
    for(int k = 2; k <= cnt; k <<= 1)
        for(int i = 0,j; i < cnt; i += k) {
            wn = Complex(cos(2 * PI / k),flag * sin(2 * PI / k));
            for(w = 1.0,j = 0; j < k >> 1; ++j,w *= wn) {
                t = w * A[i + j + (k >> 1)];
                A[i + j + (k >> 1)] = A[i + j] - t;
                A[i + j] += t;
            }
        }
    if(!~flag)
        for(int i = 0; i < cnt; ++i)
            A[i] /= cnt;
}

Complex A[MAX],B[MAX];

int cnt;
double src[MAX],ans[MAX];

int main()
{
    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] *= B[i];
    FFT(A,l,-1);
    for(int i = 0; i < cnt; ++i)
        ans[i] = A[i].x;
    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] *= B[i];
    FFT(A,l,-1);
    for(int i = 0; i < cnt; ++i)
        ans[i] -= A[cnt - i - 1].x;

    for(int i = 0; i < cnt; ++i)
        printf("%lf\n",ans[i]);
    return 0;
}
时间: 2024-10-15 08:05:41

BZOJ 3527 ZJOI 2014 力 FFT的相关文章

BZOJ[3527],[ZJOI2014]力(FFT)

BZOJ[3527],[ZJOI2014]力(FFT) 题意: 给出\(n\)个数\(q_i\),给出\(Fj\)的定义如下: \(F_j=\sum \limits _ {i < j} \frac{q_iq_j}{(i-j)^2}-\sum \limits _{i >j} \frac{q_iq_j}{(i-j)^2}.\) 令\(E_i=F_i/q_i\),求\(E_i\). 题解: 一开始没发现求\(E_i\)... 其实题目还更容易想了... \(E_i=\sum\limits _{j&l

【BZOJ 3527】 [Zjoi2014]力

3527: [Zjoi2014]力 Description 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. Input 第一行一个整数n. 接下来n行每行输入一个数,第i行表示qi. Output n行,第i行输出Ei. 与标准答案误差不超过1e-2即可. Sample Input 5 4006373.885184 15375036.435759 1717456.469144 8514941.004912 1410681.345880 Sample Output -16838

【BZOJ】3527: [Zjoi2014]力 FFT

[参考]「ZJOI2014」力 - FFT by menci [算法]FFT处理卷积 [题解]将式子代入后,化为Ej=Aj-Bj. Aj=Σqi*[1/(i-j)^2],i=1~j-1. 令f(i)=qi,g(i)=1/i^2,定义f(0)=g(0)=0(方便卷积). Aj=Σf(i)*g(j-i),i=0~j-1,标准的卷积形式. 而对于Bj,将g反转后就是和为i+n-1的标准卷积形式了. 第一次FFT后,记得对a数组后半部分清零后再进行第二次FFT. 复杂度O(n log n). #incl

[Zjoi2014]力 FFT

#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; typedef double dd; const dd pi=acos(0.0)*2; #define N 400005 struct P{ dd x,y; P(dd A=0.0,dd B=0.0){ x=A; y=B; } P

[Zjoi2014]力(FFT/NTT)

[Zjoi2014]力(FFT,卷积) 题意:给定\(n\)个点电荷,排在单位数轴上,求每个点的场强 考虑每个\(i\)对于每个\(j\)的贡献,分析式子 \(E=\cfrac{q_i}{(j-i)^2}\) 令\(f(x)=\sum q_ix^i\) \(g(x)=\sum a_ix^i,a_i=i<0?-\frac{1}{i^2}:\frac{1}{i^2}\) \(g(x)\)每一项\(x\)的指数其实是\(j-i\)的值 求\(f(x)\cdot g(x)\)即可,注意负数系数的话偏移一

BZOJ 3527: [Zjoi2014]力 FFT

3527: [Zjoi2014]力 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.34

[BZOJ 3527][Zjoi2014]力(FFT)

Description 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. Solution 设fi=qi gi=1/i/i(这里如果写成i*i可能会爆int) 那前半部分就是∑fi*gj-i 发现是一个卷积的形式 后半部分把数组反一下同理 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #define

数学(FFT):BZOJ 3527 [Zjoi2014]力

题目在这里:http://wenku.baidu.com/link?url=X4j8NM14MMYo8Q7uPE7-7GjO2_TXnMFA2azEbBh4pDf7HCENM3-hPEl4mzoe2wSoblrSOvMirfS7PsQ1OVjsdaCJhEaGNCpuUxFKoPvNvXa 裸的FFT,小心i*i爆int!!! 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #includ

bzoj 3527: [Zjoi2014]力【FFT】

大力推公式,目标是转成卷积形式:\( C_i=\sum_{j=1}^{i}a_jb_{i-j} \) 首先下标从0开始存,n-- \[ F_i=\frac{\sum_{j<i}\frac{q_jq_i}{(j-i)^2}-\sum_{j>i}\frac{q_jq_i}{(j-i)^2}}{q_i} \] \[ F_i=\sum_{j<i}\frac{q_j}{(j-i)^2}-\sum_{j>i}\frac{q_j}{(j-i)^2} \] 设 \[ a_i=\sum_{j<