3527: [Zjoi2014]力 FFT

来源:互联网 发布:流畅的python 编辑:程序博客网 时间:2024/05/17 05:02

整理一下是个卷积。FFT。

#include<iostream>#include<cstdio>#include<cmath>using namespace std;const int N=100005;const double PI=acos(-1);int n;struct C{    double real,i;    C (double a=0,double b=0) {real=a,i=b;}    C operator+(C a) {return C(real+a.real,i+a.i);}    C operator-(C a) {return C(real-a.real,i-a.i);}    C operator*(C a) {return C(real*a.real-i*a.i,real*a.i+i*a.real);}};int rev[N<<2];C a[N<<2],b[N<<2],c[N<<2],d[N<<2],e[N<<2];double ans[N];inline void FFT(C x[],int T){    for (int i=0;i<n;i++)        if (rev[i]<i) swap(x[i],x[rev[i]]);    for (int i=2;i<=n;i<<=1)    {        C wn(cos(2*PI/i),T*sin(2*PI/i));        for (int j=0;j<n;j+=i)        {            C tmp,t,w(1,0);            for (int k=0;k<(i>>1);k++)            {                tmp=x[j+k];                t=w*x[j+k+(i>>1)];                x[j+k]=tmp+t;                x[j+k+(i>>1)]=tmp-t;                w=w*wn;            }        }    }}int main(){    scanf("%d",&n);    int tmp=n;    int m=n<<1; n=1;    while (n<m) n<<=1;    for (int i=0;i<tmp;i++)        scanf("%lf",&a[i].real),e[i]=a[i];    for (int i=0;i<tmp;i++)        b[i].real=(double)1/(i+1)/(i+1);    for (int i=0;i<n;i++)        rev[i]=(rev[i>>1]>>1)|((i&1)?n>>1:0);    FFT(a,1); FFT(b,1);    for (int i=0;i<n;i++)        c[i]=a[i]*b[i];    FFT(c,-1);    for (int i=0;i<n;i++)        a[i].real=a[i].i=0.0;    for (int i=0;i<tmp;i++)        a[i]=e[tmp-i-1];    FFT(a,1);     for (int i=0;i<n;i++)        d[i]=a[i]*b[i];    FFT(d,-1);    for (int i=1;i<=tmp;i++)        ans[i]=(i==1?0:(c[i-2].real/n))-(i==tmp?0:(d[tmp-1-i].real/n));    for (int i=1;i<=tmp;i++)        printf("%.3lf\n",ans[i]);    return 0;}
0 0
原创粉丝点击