【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
原文地址:https://www.cnblogs.com/wjyi/p/5548627.html