码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3527 [Zjoi2014]力

时间:2017-02-22 13:17:14      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:g++   string   double   style   定义   技术   www   amp   cstring   

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

正解:FFT。

不难发现,这个式子可以分解成两个多项式,即0+q[1]x0+q[2]x0^2+q[3]xo^3+...+q[n]x0^n,和0+1/(1*1)x0+1/(2*2)x0^2+1/(3*3)x0^3+...+1/(n*n)x0^n。然后FFT以后就取1..n项,如果是减法那一个就是把第一个多项式倒过来,并且把最后的答案也倒过来,前面那个答案与它相减就好。

 

//It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1<<30)
#define pi acos(-1)
#define NN (500010)
#define il inline
#define RG register
#define ll long long
#define C complex<double>
 
using namespace std;
 
int rev[NN],n,N,M,lg;
double q[NN],ans[NN];
C a[NN],b[NN],c[NN];
 
il void FFT(C *a,RG int n,RG int f){
    for (RG int i=0;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]);
    for (RG int i=1;i<n;i<<=1){
    C wn(cos(pi/i),sin(f*pi/i)),x,y;
    for (RG int j=0;j<n;j+=(i<<1)){
        C w(1,0);
        for (RG int k=0;k<i;++k,w*=wn){
        x=a[j+k],y=w*a[j+k+i];
        a[j+k]=x+y,a[j+k+i]=x-y;
        }
    }
    }
    return;
}
 
il void work(){
    scanf("%d",&n); for (RG int i=1;i<=n;++i) scanf("%lf",&q[i]); for (RG int i=1;i<=n;++i) a[i]=q[i];
    for (RG int i=1;i<=n;++i) b[i]=1.0/i/i; M=2*(n+1); for (N=1;N<=M;N<<=1) lg++;
    for (RG int i=0;i<=N;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)); FFT(a,N,1),FFT(b,N,1);
    for (RG int i=0;i<N;++i) a[i]*=b[i]; FFT(a,N,-1);
    for (RG int i=1;i<=n;++i) c[i]=q[n-i+1]; FFT(c,N,1);
    for (RG int i=0;i<N;++i) c[i]*=b[i]; FFT(c,N,-1);
    for (RG int i=1;i<=n;++i) ans[i]=a[i].real()/N-c[n-i+1].real()/N;
    for (RG int i=1;i<=n;++i) printf("%0.3lf\n",ans[i]); return;
}
 
int main(){
    work();
    return 0;
}

 

bzoj3527 [Zjoi2014]力

标签:g++   string   double   style   定义   技术   www   amp   cstring   

原文地址:http://www.cnblogs.com/wfj2048/p/6427979.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!