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

P3338 [ZJOI2014]力 /// FFT 公式转化翻转

时间:2018-08-13 15:56:06      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:int   http   com   zjoi   target   while   names   pac   space   

题目大意:

https://www.luogu.org/problemnew/show/P3338

题解

技术分享图片

技术分享图片
#include <bits/stdc++.h>
#define N 300005
#define PI acos(-1.0)
using namespace std;

struct cpx {
    double x,y;
    cpx (double a=0.0,double b=0.0) { x=a; y=b; }
    cpx operator - (const cpx &b)const { return cpx(x-b.x, y-b.y); }
    cpx operator + (const cpx &b)const { return cpx(x+b.x, y+b.y); }
    cpx operator * (const cpx &b)const { return cpx(x*b.x-y*b.y, x*b.y+y*b.x); }
}f1[N], f2[N], g[N];
int n, l, len, r[N];

void fft(cpx a[],double on)
{
    for(int i=0;i<len;i++)
        if(i<r[i]) swap(a[i],a[r[i]]);
    for(int i=1;i<len;i<<=1) {
        cpx wn(cos(PI/i),on*sin(PI/i));
        for(int j=0;j<len;j+=(i<<1)) {
            cpx w(1,0);
            for(int k=0;k<i;k++,w=w*wn) {
                cpx u=a[j+k], v=w*a[j+k+i];
                a[j+k]=u+v, a[j+k+i]=u-v;
            }
        }
    }
}

void solve()
{
    fft(f1,1); fft(f2,1); fft(g,1);
    for(int i=0;i<=len;i++)
        f1[i]=f1[i]*g[i], f2[i]=f2[i]*g[i];
    fft(f1,-1); fft(f2,-1);
    for(int i=0;i<=len;i++)
        f1[i].x=f1[i].x/len, f2[i].x=f2[i].x/len;
    for(int i=1;i<=n;i++)
        printf("%.3f\n",-f2[n+1-i].x+f1[i].x);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%lf",&f1[i].x);
        f2[n+1-i].x=f1[i].x;
        g[i].x=(double)(1.0/i/i);
    }

    len=1; l=0;
    while(len<(n<<1)) len<<=1, l++;
    for(int i=0;i<=len;i++)
        r[i]=( r[i>>1]>>1 )|( (i&1)<<(l-1) );

    solve();

    return 0;
}
View Code

 

P3338 [ZJOI2014]力 /// FFT 公式转化翻转

标签:int   http   com   zjoi   target   while   names   pac   space   

原文地址:https://www.cnblogs.com/zquzjx/p/9468337.html

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