【BZOJ-3527】力 FFT

3527: [Zjoi2014]力

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

Solution

一道裸的FFT,我瞪了快一节课...

先两边同除$p_{j}$就可以直接得到$E_{j}$的关于$q$的关系..然后就可以看出是一个卷积的形式了..

主要是光想直接$A\bigotimes B=E$,实际上正反求一下相减就好..

然后这里discuss里提醒了我一件事..爆int

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
struct Complex{
	double r,i;
	Complex(double R=0.0,double I=0.0) {r=R; i=I;}
	Complex operator + (const Complex & A) const {return Complex(r+A.r,i+A.i);}
	Complex operator - (const Complex & A) const {return Complex(r-A.r,i-A.i);}
	Complex operator * (const Complex & A) const {return Complex(r*A.r-i*A.i,r*A.i+i*A.r);}
};
#define MAXN 600010
#define Pai acos(-1.0)
Complex A[MAXN],B[MAXN],C[MAXN],D[MAXN];
int N,len;
double a[MAXN];
inline void Prework()
{
	len=1;
	while (len<((N-1)<<1)) len<<=1;
	for (int i=0; i<=N-1; i++) A[i]=Complex(a[i],0);
	for (int i=N; i<len; i++) A[i]=Complex(0,0);
	for (int i=0; i<=N-1; i++) B[i]=Complex(a[N-1-i],0);
	for (int i=N; i<len; i++) B[i]=Complex(0,0);
	for (int i=0; i<=N-1; i++) if (i) D[i]=C[i]=Complex(1.0/i/i,0);
	for (int i=N; i<len; i++) D[i]=C[i]=Complex(0,0);
}
inline void Rader(Complex *x)
{
    for (int i=1,j=len>>1,k; i<len-1; i++)
        {
            if (i<j) swap(x[i],x[j]);
            k=len>>1;
            while (j>=k) j-=k,k>>=1;
            if (j<k) j+=k;
        }
}
inline void DFT(Complex *x,int opt)
{
    Rader(x);
    for (int h=2; h<=len; h<<=1)
        {
            Complex Wn( cos(opt*2*Pai/h),sin(opt*2*Pai/h) );
            for (int i=0; i<len; i+=h)
                {
                    Complex W(1,0);
                    for (int j=i; j<i+h/2; j++)
                        {
                            Complex u=x[j],t=W*x[j+h/2];
                            x[j]=u+t; x[j+h/2]=u-t;
                            W=W*Wn;
                        }
                }
        }
    if (opt==-1)
        for (int i=0; i<len; i++) x[i].r/=len;
}
inline void FFT(Complex *x,Complex *y)
{
	DFT(x,1); DFT(y,1);
	for (int i=0; i<len; i++) x[i]=x[i]*y[i];
	DFT(x,-1);
}
int main()
{
	scanf("%d",&N);
	for (int i=0; i<N; i++) scanf("%lf",&a[i]);
	Prework();
//	for (int i=0; i<len; i++) printf("%.6lf\n",A[i].r); puts("=================");
//	for (int i=0; i<len; i++) printf("%.6lf\n",B[i].r); puts("=================");
//	for (int i=0; i<len; i++) printf("%.6lf\n",C[i].r); puts("=================");
	FFT(A,C); FFT(B,D);
	for (int i=0; i<N; i++) printf("%.3lf\n",A[i].r-B[N-1-i].r);
	return 0;
}

  

时间: 2024-10-18 05:48:52

【BZOJ-3527】力 FFT的相关文章

BZOJ 3527 力

fft推下公式.注意两点: (1)数组从0开始以避免出错. (2)i*i爆long long #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<complex> #define pi acos(-1) #define maxn 400500 using namespace std; typ

[BZOJ]3527 力(ZJOI2014)

第一次背出FFT模板,在此mark一道裸题. 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 -1

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]力 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

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 MA

数学(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