zoukankan      html  css  js  c++  java
  • 【bzoj2179】FFT快速傅立叶 FFT模板

    2016-06-01  09:34:54

    很久很久很久以前写的了。。。

    今天又比较了一下效率,貌似手写复数要快很多。

    贴一下模板:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<complex>
     9 #define ll long long
    10 #define N 500020
    11 using namespace std;
    12 int read(){
    13   int x=0,f=1;char ch=getchar();
    14   while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    15   while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    16   return x*f;
    17 }
    18 struct CD{
    19   double a,b;
    20   CD(double x=0,double y=0){a=x;b=y;}
    21   friend CD operator +(CD n1,CD n2){return CD(n1.a+n2.a,n1.b+n2.b);}
    22   friend CD operator -(CD n1,CD n2){return CD(n1.a-n2.a,n1.b-n2.b);}
    23   friend CD operator *(CD n1,CD n2){return CD(n1.a*n2.a-n1.b*n2.b,n1.a*n2.b+n1.b*n2.a);}
    24 };
    25 int n,m,bit=0;
    26 const long double Pi=acos(-1.0);
    27  
    28 void FFT(CD *a,int n,int type){
    29   for(int i=0,j=0;i<n;i++) {
    30     if(j>i)swap(a[i],a[j]);
    31     int k=n;
    32     while(j&(k >>= 1))j&=~k;
    33     j|=k;
    34   }
    35   for(int i=1;i<=bit;i++){
    36     CD w_n(cos(2*type*Pi/(1<<i)),sin(2*type*Pi/(1<<i)));
    37     for(int j=0;j<(1<<bit);j+=(1<<i)){
    38       CD w(1,0);
    39       for(int k=j;k<j+(1<<(i-1));k++){
    40          CD tmp=a[k],tt=w*a[k+(1<<(i-1))];
    41          a[k]=a[k]+tt;
    42          a[k+(1<<(i-1))]=tmp-tt;
    43          w=w*w_n;
    44       }
    45     }
    46   }
    47   if(type<0) for(int i=0;i<(1<<bit);i++) a[i].a=(a[i].a+0.5)/(1<<bit); 
    48 }
    49  
    50 CD poly1[N],poly2[N];
    51 int c[N*2];
    52  
    53 char ch[N];
    54 int main (){
    55   n=read();
    56   scanf("%s",ch+1);
    57   for(int i=0;i<n;i++)poly1[i]=(double)(ch[n-i]-'0');
    58   scanf("%s",ch+1);
    59   for(int i=0;i<n;i++)poly2[i]=(double)(ch[n-i]-'0');
    60   bit=1;
    61   while(1<<bit<(n<<1))bit++;
    62   n=1<<bit;
    63   FFT(poly1,n,1);FFT(poly2,n,1);
    64   for(int i=0;i<n;i++)poly1[i]=poly1[i]*poly2[i];
    65   FFT(poly1,n,-1);
    66   int jin=0,top=0;
    67   for(int i=0;i<n;i++){
    68     jin+=(int)(poly1[i].a+0.5);
    69     c[++top]=jin%10;
    70     jin/=10;
    71   }
    72   while(top&&c[top]==0) top--;
    73   while(top)putchar(c[top--]+'0');
    74   return 0;
    75 }
    View Code

    2179: FFT快速傅立叶

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 2552  Solved: 1299
    [Submit][Status][Discuss]

    Description

    给出两个n位10进制整数x和y,你需要计算x*y。

    Input

    第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。

    Output

    输出一行,即x*y的结果。

    Sample Input

    1
    3
    4

    Sample Output

    12

    数据范围:
    n<=60000
  • 相关阅读:
    洛谷:P3391 【模板】文艺平衡树(Splay)
    洛谷:P2234 [HNOI2002]营业额统计
    洛谷冬令营随想
    存储过程分页说明
    前台数据验证(1)
    前台数据验证(2)
    【转载】JQuery中$.ajax()方法参数详解
    启用IIS的Gzip压缩
    使用WCF常见问题
    在使用WCF时如何生成证书认证?
  • 原文地址:https://www.cnblogs.com/wjyi/p/5548627.html
Copyright © 2011-2022 走看看