BZOJ 3527 力

Posted on 2016-08-14 11:45  ziliuziliu  阅读(122)  评论(0编辑  收藏  举报

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;
typedef complex<double> E;
int n,r[maxn],m,l=0;
double regis;
E a1[maxn],a2[maxn],b[maxn],c1[maxn],c2[maxn];
void reset()
{
    for (int i=1;i<=(m/2);i++)
        b[i].real()=(1.0)/i/i;
}
void fft(E *x,int f)
{
    for (int i=0;i<n;i++)
        if (i>r[i]) swap(x[i],x[r[i]]);
    for (int i=1;i<n;i<<=1)
    {
        E wn(cos(pi/i),f*sin(pi/i));
        for (int j=0;j<n;j+=(i<<1))
        {
            E w(1,0);
            for (int k=0;k<i;k++)
            {
                E r1,r2;
                r1=x[j+k];r2=w*x[i+j+k];
                x[j+k]=r1+r2;x[i+j+k]=r1-r2;
                w*=wn;
            }
        }
    }
    if (f==-1)
    {
        for (int i=0;i<n;i++)
            x[i]/=n;
    }
}
int main()
{
    scanf("%d",&n);n--;
    for (int i=0;i<=n;i++)
    {
        scanf("%lf",&regis);
        a1[i].real()=a2[n-i].real()=regis;
    }
    m=2*n;
    for (n=1;n<=m;n<<=1) l++;
    for (int i=0;i<n;i++) r[i]=((r[i>>1]>>1)|((i&1)<<(l-1)));
    reset();
    fft(a1,1);fft(b,1);fft(a2,1);
    for (int i=0;i<n;i++)
    {
        c1[i]=a1[i]*b[i];
        c2[i]=a2[i]*b[i];
    }
    fft(c1,-1);fft(c2,-1);
    n=m/2;
    for (int i=0;i<=n;i++)
        printf("%.3lf\n",c1[i].real()-c2[m/2-i].real());
    return 0;
}