BZOJ2179:FFT快速傅立叶(FFT)

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

Solution

FFT模板题,做的时候注意处理一下进位和前导零就好

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #define N (240000+100)
 6 using namespace std;
 7 double pi=acos(-1.0);
 8 struct complex
 9 {
10     double x,y;
11     complex (double xx=0,double yy=0)
12     {
13         x=xx; y=yy;
14     }
15 }a[N],b[N];
16 int n=-1,m=-1,t,fn,l,r[N];
17 char ch;
18 
19 complex operator + (complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
20 complex operator - (complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
21 complex operator * (complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
22 complex operator / (complex a,double b){return complex(a.x/b,a.y/b);}
23 
24 void FFT(int n,complex *a,int opt)
25 {
26     for (int i=0; i<n; ++i)
27         if (i<r[i])
28             swap(a[i],a[r[i]]);
29     for (int k=1; k<n; k<<=1)
30     {
31         complex wn=complex(cos(pi/k),opt*sin(pi/k));
32         for (int i=0; i<n; i+=(k<<1))
33         {
34             complex w=complex(1,0);
35             for (int j=0; j<k; ++j,w=w*wn)
36             {
37                 complex x=a[i+j], y=w*a[i+j+k];
38                 a[i+j]=x+y; a[i+j+k]=x-y;
39             }
40         }
41     }
42     if (opt==-1) for (int i=0; i<n; ++i) a[i]=a[i]/n;
43 }
44 
45 int main()
46 {
47     scanf("%d",&t); t--;
48     for (int i=0; i<=t; ++i)
49     {
50         ch=getchar();
51         while (ch<'0' || ch>'9') ch=getchar();
52         if (n==-1 && ch=='0') continue;
53         a[++n].x=ch-'0';
54     }
55     for (int i=0; i<=t; ++i)
56     {
57         ch=getchar();
58         while (ch<'0' || ch>'9') ch=getchar();
59         if (m==-1 && ch=='0') continue;
60         b[++m].x=ch-'0';
61     }
62     if (m==-1) m=0;
63     if (n==-1) n=0;
64     fn=1;
65     while (fn<=n+m) fn<<=1, l++;
66     for (int i=0;i<fn;++i)
67         r[i]=(r[i>>1]>>1) | ((i&1)<<(l-1));
68     
69     FFT(fn,a,1); FFT(fn,b,1);
70     for (int i=0;i<=fn;++i)
71         a[i]=a[i]*b[i];
72     FFT(fn,a,-1);
73     for (int i=n+m;i>=1;--i)
74     {
75         a[i-1].x+=(int)(a[i].x+0.5)/10;
76         a[i].x=(int)(a[i].x+0.5)%10;
77     }
78     int p=0;
79     while ((int)(a[p].x+0.5)==0 && p<n+m) p++; 
80     for (int i=p;i<=n+m;++i)
81         printf("%d",(int)(a[i].x+0.5));
82 }
posted @ 2018-04-13 16:30  Refun  阅读(148)  评论(0编辑  收藏  举报