fft

板子

const int N=1e6;
struct FFT{
  const double pi=acos(-1);
  struct cp{
      double x,y;
      cp operator +(const cp &o)const{return (cp){x+o.x,y+o.y};}
      cp operator -(const cp &o)const{return (cp){x-o.x,y-o.y};}
      cp operator *(const cp &o)const{return (cp){x*o.x-y*o.y,y*o.x+x*o.y};}
      cp operator *(const double &o)const{return (cp){x*o,y*o};}
      cp operator !()const{return (cp){x,-y};}
  }a[N],b[N],c[N],w[N];
  int l,r[N];
  int n,m;
  void fft_init()
  {
      l=0; for (n=1;n<=m;n<<=1) l++;
  }
  void fft_clear()
  {
      rep(i,0,n) a[i].x=a[i].y=b[i].x=b[i].y=0;
  }
  void fft(cp x[],int k,int v){
      for(int i=0,j=0;i<k;i++)
      {
          if(i>j)std::swap(x[i],x[j]);
          for(int l=k>>1;(j^=l)<l;l>>=1);
      }
      w[0]=(cp){1,0};
      for(int i=2;i<=k;i<<=1){
          cp g=(cp){cos(2*pi/i),(v?-1:1)*sin(2*pi/i)};
          for(int j=(i>>1);j>=0;j-=2)w[j]=w[j>>1];
          for(int j=1;j<i>>1;j+=2)w[j]=w[j-1]*g;
          for(int j=0;j<k;j+=i){
              cp *a=x+j,*b=a+(i>>1);
              for(int l=0;l<i>>1;l++){
                  cp o=b[l]*w[l];
                  b[l]=a[l]-o;
                  a[l]=a[l]+o;
              } 
        }
    }
    if(v)for(int i=0;i<k;i++)x[i]=(cp){x[i].x/k,x[i].y/k};
  }
  IL void get_cj(ll *A,ll *B,ll *C,int len)
  {
      rep(i,0,len) (i&1?a[i>>1].y:a[i>>1].x)=A[i];
      rep(i,0,len) (i&1?b[i>>1].y:b[i>>1].x)=B[i];
      m=len;
      fft_init();
      fft(a,n,0); fft(b,n,0);
      for(int i=0;i<n;i++){
        int j=(n-1)&(n-i);
        c[i]=(a[i]*b[i]*4-(a[i]-!a[j])*(b[i]-!b[j])*(((i&n>>1)?(cp){1,0}-w[i^n>>1]:w[i]+(cp){1,0})))*0.25;
      }
      fft(c,n,1);
      rep(i,0,len)
        if (i&1) C[i]=(ll)(c[i>>1].y+0.1);
        else C[i]=(ll)(c[i>>1].x+0.1);
      fft_clear();
  }
}F;

 

posted @ 2021-11-27 13:57  尹吴潇  阅读(152)  评论(0编辑  收藏  举报