洛谷:[ZJOI2014]力(FFT)

点我查看题目

题目描述

给出n个数qi,给出Fj的定义如下:

F_j = \sum_{ij}\frac{q_i q_j}{(i-j)^2 }Fj​=∑ij​(i−j)2qi​qj​​

令Ei=Fi/qi,求Ei.

输入输出格式

输入格式:

 

第一行一个整数n。

接下来n行每行输入一个数,第i行表示qi。

 

输出格式:

 

n行,第i行输出Ei。

与标准答案误差不超过1e-2即可。

 

输入输出样例

输入样例#1: 复制

5
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880

输出样例#1: 复制

-16838672.693
3439.793
7509018.566
4595686.886
10903040.872

说明

对于30%的数据,n≤1000。

对于50%的数据,n≤60000。

对于100%的数据,n≤100000,0

[spj 0.01]

思路:预处理C[i] = 1/(i*i)之后就是求卷积,右半部分只需要将Q数组反转,就能用卷积解决,FFT。

# include 
struct complex{
    double x,y;
    complex(double xx=0,double yy=0){x=xx;y=yy;}
    complex operator +(const complex &b){return complex(b.x+x,b.y+y);}
    complex operator -(const complex &b){return complex(-b.x+x,-b.y+y);}
    complex operator *(const complex &b){return complex(x*b.x-y*b.y,x*b.y+y*b.x);}
}A[410010],B[410010],C[410010];
const double pi=acos(-1.0);
int n,limit=1,cnt=0,r[410010];
void fft(complex *a,double type){
    int i,mid,j,k,R;complex w,wn,x,y;
    for(i=0;i>1]>>1)|((i&1)<<(cnt-1)));
    fft(A,  1);
    fft(B,  1);
    fft(C,  1);
    for(int i=0; i<=limit; ++i) A[i] = A[i]*C[i], B[i] = B[i]*C[i];
    fft(A,  -1);
    fft(B,  -1);
    for(int i=1; i<=n; ++i){
        double tmp = A[i].x/limit - B[n-i+1].x/limit;//整数要加0.5再取整
        printf("%.4f\n",tmp);
    }
}

 

你可能感兴趣的:(数论)