BZOJ 2179FFT快速傅立叶

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2179

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

题解:FFT,不会的可以膜拜陈老师(非clj)QQ:297086016

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #define inf 1<<30
 6 #define maxm 270005
 7 #define pi acos(-1)
 8 using namespace std;
 9 struct F{
10     double rea,ima;    
11     F operator +(const F &x){return (F){rea+x.rea,ima+x.ima};}
12     F operator -(const F &x){return (F){rea-x.rea,ima-x.ima};}
13     F operator *(const F &x){return (F){rea*x.rea-ima*x.ima,rea*x.ima+ima*x.rea};}
14 }a[maxm],b[maxm],c[maxm],w,wn,t1,t2;
15 int n,m,l,ans[maxm],rev[maxm];
16 void read(F *a)
17 {
18     char ch;
19     while (ch=getchar(),ch<'0'||ch>'9');
20     for (int i=m-1; ch>='0'&&ch<='9';ch=getchar(),i--) a[i].rea=ch-'0';
21 }
22 int re(int v)
23 {
24     int t=0;
25     for (int i=0; i<l; i++) t<<=1,t|=v&1,v>>=1;
26     return t;
27 }
28 void fft(F *a,int type)
29 {
30     for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
31     for (int s=2; s<=n; s<<=1)
32     {
33         wn=(F){cos(type*2*pi/s),sin(type*2*pi/s)};
34         for (int i=0; i<n; i+=s)
35         {
36             w=(F){1,0};
37             for (int j=i; j<(i+(s>>1)); j++,w=w*wn)
38             {
39                 t1=a[j],t2=w*a[j+(s>>1)];
40                 a[j]=t1+t2,a[j+(s>>1)]=t1-t2;
41             }
42         }
43     }
44 }
45 int main()
46 {
47     scanf("%d\n",&m);
48     for (n=1; n<(m<<1); n<<=1) l++;
49     for (int i=0; i<n; i++) rev[i]=re(i);
50     read(a); read(b);
51     fft(a,1); fft(b,1);
52     for (int i=0; i<n; i++) c[i]=a[i]*b[i];
53     fft(c,-1);
54     for(int i=0;i<n;i++) ans[i]=int(c[i].rea/n+0.5);
55     for(int i=0;i<n;i++) ans[i+1]+=ans[i]/10,ans[i]=ans[i]%10;
56     int pps=n-1;while(ans[pps]==0&&pps)pps--;
57     for(;pps>=0;pps--)printf("%d",ans[pps]);printf("\n");
58     return 0;
59 }
View Code

 

posted @ 2016-06-17 21:08  ACist  阅读(191)  评论(0编辑  收藏  举报