zoukankan      html  css  js  c++  java
  • FFT多项式乘法加速

    FFT基本操作。。。讲解请自己看大学信号转置系列。。。

    15-5-30更新:改成结构体的,跪烂王学长啊啊啊啊机智的static。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 #pragma comment(linker,"/STACK:10240000,10240000")
    10 using namespace std;
    11 const double PI=acos(-1.0);
    12 const int maxn=800000+10;
    13 struct FFT{
    14     struct cox{
    15         double r,i;cox(double _r = 0.0,double _i = 0.0){r=_r;i=_i;}
    16         cox operator +(const cox &b){return cox(r+b.r,i+b.i);}
    17         cox operator -(const cox &b){return cox(r-b.r,i-b.i);}
    18         cox operator *(const cox &b){return cox(r*b.r-i*b.i,r*b.i+i*b.r);}
    19     }f[maxn];int len,lenx;
    20     void init(int*s,int L,int Len){
    21         len=L;lenx=Len;
    22         for(int i=0;i<L;i++) f[i]=cox(s[L-1-i],0);
    23         for(int i=L;i<Len;i++) f[i]=cox(0,0);return;
    24     }
    25     void change(){
    26         for(int i=1,j=lenx>>1;i<lenx-1;i++){
    27             if(i<j)swap(f[i],f[j]);
    28             int k=lenx>>1;
    29             while(j>=k) j-=k,k>>=1;
    30             if(j<k) j+=k;
    31         } return;
    32     }
    33     void cal(int tp){
    34         change();
    35         for(int h=2;h<=lenx;h<<=1){
    36             double tr=-tp*2*PI/h;
    37             cox wn(cos(tr),sin(tr));
    38             for(int j=0;j<lenx;j+=h){
    39                 cox w(1,0);
    40                 for(int k=j;k<j+(h>>1);k++){
    41                     cox u=f[k],t=w*f[k+(h>>1)];
    42                     f[k]=u+t;f[k+(h>>1)]=u-t;w=w*wn;
    43                 }
    44             }
    45         } if(tp==-1) for(int i=0;i<lenx;i++) f[i].r/=lenx;return;
    46     }
    47 };
    48 void mul(int*s1,int*s2,int L1,int L2,int&L,int*ans){
    49     L=1;while(L<L1<<1||L<L2<<1) L<<=1;
    50     static FFT a,b;a.init(s1,L1,L);b.init(s2,L2,L);a.cal(1);b.cal(1);
    51     for(int i=0;i<L;i++) a.f[i]=a.f[i]*b.f[i];a.cal(-1);
    52     for(int i=0;i<L;i++) ans[i]=(int){a.f[i].r+0.5};return;
    53 }
    54 int s1[maxn>>1],s2[maxn>>1],ans[maxn],L1,L2,L;
    55 void init(){
    56     char ch;int tot;
    57     do ch=getchar(); while(!isdigit(ch));tot=0;
    58     while(isdigit(ch)){s1[tot++]=ch-'0';ch=getchar();}L1=tot;
    59     do ch=getchar(); while(!isdigit(ch));tot=0;
    60     while(isdigit(ch)){s2[tot++]=ch-'0';ch=getchar();}L2=tot;
    61     mul(s1,s2,L1,L2,L,ans);
    62     return;
    63 }
    64 void work(){
    65     for(int i=0;i<L;i++){
    66         ans[i+1]+=ans[i]/10;ans[i]%=10;
    67     } L=L1+L2-1;return;
    68 }
    69 void print(){
    70     while(ans[L]<=0&&L>0) L--;
    71     for(int i=L;i>=0;i--) putchar(ans[i]+'0');
    72     return;
    73 }
    74 int main(){init();work();print();return 0;}

    原来写的丑哭了TAT

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 using namespace std;
    10 const double PI=acos(-1.0);
    11 struct complex{
    12     double r,i;
    13     complex(double _r = 0.0,double _i = 0.0){r=_r;i=_i;}
    14     complex operator +(const complex &b){return complex(r+b.r,i+b.i);}
    15     complex operator -(const complex &b){return complex(r-b.r,i-b.i);}
    16     complex operator *(const complex &b){return complex(r*b.r-i*b.i,r*b.i+i*b.r);}
    17 };
    18 void change(complex y[],int len){
    19     int i,j,k;
    20     for(i=1,j=len/2;i<len-1;i++){
    21         if(i<j)swap(y[i],y[j]);
    22         k=len/2;
    23         while(j>=k) j-=k,k/=2;
    24         if(j<k) j+=k;
    25     } return;
    26 }
    27 void fft(complex y[],int len,int on){
    28     change(y,len);
    29     for(int h=2;h<=len;h<<=1){
    30         complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
    31         for(int j=0;j<len;j+=h){
    32             complex w(1,0);
    33             for(int k=j;k<j+h/2;k++){
    34                 complex u=y[k],t=w*y[k+h/2];
    35                 y[k]=u+t;
    36                 y[k+h/2]=u-t;
    37                 w=w*wn;
    38             }
    39         }
    40     }
    41     if(on==-1) for(int i=0;i<len;i++) y[i].r/=len;
    42     return;
    43 }
    44 const int MAXN=2000+10;
    45 complex x1[MAXN],x2[MAXN];
    46 char str1[MAXN>>1],str2[MAXN>>1];
    47 int sum[MAXN];
    48 inline int read(){
    49     int x=0,sig=1;char ch=getchar();
    50     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    51     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    52     return x*=sig;
    53 }
    54 inline void write(int x){
    55     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    56     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    57     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    58 }
    59 int len,len1,len2;
    60 void init(){
    61     scanf("%s%s",str1,str2);
    62     len1=strlen(str1),len2=strlen(str2),len=1;
    63     return;
    64 }
    65 void work(){
    66     while(len<len1<<1||len<len2<<1) len<<=1;
    67     for(int i=0;i<len1;i++) x1[i]=complex(str1[len1-1-i]-'0',0);
    68     for(int i=len1;i<len;i++) x1[i]=complex(0,0);
    69     for(int i=0;i<len2;i++) x2[i]=complex(str2[len2-1-i]-'0',0);
    70     for(int i=len2;i<len;i++) x2[i]=complex(0,0);
    71     fft(x1,len,1);fft(x2,len,1);
    72     for(int i=0;i<len;i++) x1[i]=x1[i]*x2[i];
    73     fft(x1,len,-1);
    74     for(int i=0;i<len;i++) sum[i]=(int)(x1[i].r+0.5);
    75     for(int i=0;i<len;i++){
    76         sum[i+1]+=sum[i]/10;
    77         sum[i]%=10;
    78     } len=len1+len2-1;return;
    79 }
    80 void print(){
    81     while(sum[len]<=0&&len>0) len--;
    82     for(int i=len;i>=0;i--) putchar(sum[i]+'0');
    83     return;
    84 }
    85 int main(){init();work();print();return 0;}
  • 相关阅读:
    我爬取了爬虫岗位薪资,分析后发现爬虫真香
    红薯,撑起父亲的快乐,让我揪心
    跨域问题服务端解决办法 Request header field Authorization is not allowed by Access-Control-Allow-Headers
    antdvue2.x 使用阿里iconfont自定义组件iconfont
    前端 crypto-js aes 加解密
    jsencrypt加密解密字符串
    CryptoJS base64使用方法
    客户端js生成rsa 密钥对
    js动态添加style样式
    PHP 使用非对称加密算法(RSA)
  • 原文地址:https://www.cnblogs.com/chxer/p/4507345.html
Copyright © 2011-2022 走看看