FFT

背诵全文

#include<complex>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define C complex<double>
using namespace std;
inline int gi()
{
    int res=0,fh=1;char ch=getchar();
    while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
    if(ch=='-')fh=-1,ch=getchar();
    while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    return fh*res;
}
const int MAXN=270050;
const double pi=acos(-1);
int n,m,L;
int R[MAXN];
C a[MAXN],b[MAXN];
void fft(C *a,int f)
{
    for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);//交换位置
    for(int i=1;i<n;i<<=1)//待合并区间长度
    {
        C wn(cos(pi/i),sin(f*pi/i)),x,y;//这里就不用再*2了,因为合并后的区间长度是i的两倍
        for(int j=0;j<n;j+=i<<1)//起始位置
        {
            C w(1,0);
            for(int k=0;k<i;k++,w*=wn)//第k个
            {
                x=a[j+k];y=w*a[j+i+k];
                a[j+k]=x+y;
                a[j+i+k]=x-y;
            }
        }
    }
}
int main()
{
    n=gi();m=gi();
    for(int i=0;i<=n;i++)a[i]=gi();
    for(int i=0;i<=m;i++)b[i]=gi();
    m+=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));//递推
    fft(a,1);fft(b,1);
    for(int i=0;i<=n;i++)a[i]*=b[i];
    fft(a,-1);
    for(int i=0;i<=m;i++)printf("%d ",int(a[i].real()/n+0.5));
    return 0;
}
View Code

 

posted @ 2017-12-11 21:34  探险家Mr.H  阅读(164)  评论(0编辑  收藏  举报