复制代码

板子 FFT

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
         freopen("out","w",stdout); 
 
const int    sz = (int)1e7 + 5; 
const double Pi =acos(-1.0);
#define FOR(i, a, b)  for(int i=(a); i<(b); i++)
#define REP(i, a, b)  for(int i=(a); i<=(b); i++)
#define DOWN(i, a, b) for(int i=(a); i>=(b); i--)
 
inline int read()
{
    int x=0;int f =1;
    char c=getchar();
    while(!isdigit(c))
    {
        if(x=='-') f=-1;
        c=getchar();
    }
    while(isdigit(c))
    {
        x=x*10+(c&15);
        c=getchar();
    }
    return x;
} 
struct com
{
    double x ,y;
    com(double xx=0,double yy=0){ x=xx,y=yy;}
}a[sz],b[sz];
com operator + (com a,com b){return com(a.x+b.x,a.y+b.y);}
com operator - (com a,com b){return com(a.x-b.x,a.y-b.y);}
com operator * (com a,com b){return com(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
#if 0
void fft(int limit,com * a,int type)
{
    if(limit ==1)return ;
    com a1[limit>>1],a2[limit>>1] ;
     for(int i=0;i<=limit;i+=2)
     {
        a1[i>>1]=a[i],a2[i>>1]=a[i+1];
     } 
     fft(limit>>1,a1,type);
     fft(limit>>1,a2,type);
     com Wn = com(cos(2.0*Pi/limit),type*sin(2.0*Pi/limit)) ;
     com w = com(1,0);
     for(int i =0;i<(limit>>1);i++,w=w*Wn)
     {
        a[i]=a1[i]+w*a2[i],a[i+(limit>>1)]=a1[i]-w*a2[i];
     }

}
#endif 
int limit=1,l,r[sz];
void fft(com* a,int type)
{
    for(int i=0;i<limit;i++)
        if(i<r[i])swap(a[i],a[r[i]]);
    for(int mid = 1;mid<limit;mid<<=1)
    {
        com Wn(cos(Pi/mid),type*sin(Pi/mid));
        for(int R =mid<<1,j=0;j<limit;j+=R)
        {
            com w(1,0);
            for(int k =0;k<mid;k++,w=w*Wn)
            {
                com x =a[j+k],y=w*a[j+mid+k];
               a[j+k] = x+y;
               a[j+mid+k]=x-y ;     
            }
        }
    }
}
int main()
{
   // LOACL
    int n =read(),m=read();
    
  
    REP(i,0,n) a[i].x =read();
    REP(i,0,m) b[i].x =read();
#if 0 
    int limit =1;while(limit<=n+m) limit<<=1;
    fft(limit,a,1);
    fft(limit,b,1);
#endif

    while(limit<=n+m)limit<<=1,l++;

    for(int i=0;i<limit;i++)
        r[i]=(r[i>>1]>>1)|(i&1)<<(l-1);
    fft(a,1),fft(b,1);
    REP(i,0,limit) a[i]=a[i]*b[i];
    fft(a,-1);
    REP(i,0,n+m)  printf("%d ",(int)(a[i].x/limit+0.5)); //cout<<(int)(a[i].x/limit +0.5)<<" ";
 
    return 0;
}
View Code

 

posted @ 2018-05-17 16:50  pg633  阅读(145)  评论(0编辑  收藏  举报