bzoj2194: 快速傅立叶之二

了解到了FFT求卷积,但是还是感性的认识。。

取反就可以了。输出一定要加int!!!!

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const double pi=acos(-1.0);

struct Complex
{
    double r,i;
    Complex(){}
    Complex(double _r,double _i){r=_r, i=_i;}
    friend Complex operator +(Complex x,Complex y){return Complex(x.r+y.r,x.i+y.i);}
    friend Complex operator -(Complex x,Complex y){return Complex(x.r-y.r,x.i-y.i);}
    friend Complex operator *(Complex x,Complex y){return Complex(x.r*y.r-x.i*y.i,x.r*y.i+x.i*y.r);}
}A[410000],B[410000],C[410000];

int R[410000];
void fft(Complex *a,int n,int op)
{
    for(int i=0;i<n;i++)
        if(i<R[i])swap(a[i],a[R[i]]);
        
    for(int i=1;i<n;i*=2)
    {
        Complex wn(cos(pi/i),sin(pi*op/i));
        for(int j=0;j<n;j+=(i<<1))
        {
            Complex w(1,0);
            for(int k=0;k<i;k++,w=w*wn)
            {
                Complex a1=a[j+k],a2=a[j+k+i];
                a[j+k]  =a1+w*a2;
                a[j+k+i]=a1-w*a2;
            }
        }
    }
    if(op==-1)for(int i=0;i<n;i++)a[i].r/=n;
}
int main()
{
    int n,m,L=0;
    scanf("%d",&m);m--;
    for(int i=0;i<=m;i++)scanf("%lf%lf",&A[i].r,&B[m-i].r);
    m*=2;for(n=1;n<=m;n*=2)L++;
    
    
    for(int i=0;i<n;i++)R[i]=( R[i>>1]>>1 )|( (i&1) << (L-1) );

    fft(A,n,1);fft(B,n,1);
    for(int i=0;i<n;i++)C[i]=A[i]*B[i];
    
    fft(C,n,-1);
    for(int i=m/2;i<=m;i++)
        printf("%d\n",int(C[i].r+0.5));
    
    
    return 0;
}
posted @ 2017-12-04 13:47  AKCqhzdy  阅读(138)  评论(0编辑  收藏  举报