# 【BZOJ 2179】 2179: FFT快速傅立叶 (FFT)

## 2179: FFT快速傅立叶

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 3308  Solved: 1720

1
3
4

12

n<=60000

## Source

【分析】

FFT裸题。

结果的第i位 f*g(i)=f(k)*g(i-k) 【后面就会知道，这是标准的卷积形式，可以用FFT加速

FFTnlogn的，后面总结。

 1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<algorithm>
6 #include<cmath>
7 using namespace std;
8 #define Maxn 60010*4
9 const double pi=3.14159265358;
10
11 struct P
12 {
13     double x,y;
14     P() {x=y=0;}
15     P(double x,double y):x(x),y(y){}
16     friend P operator + (P x,P y) {return P(x.x+y.x,x.y+y.y);}
17     friend P operator - (P x,P y) {return P(x.x-y.x,x.y-y.y);}
18     friend P operator * (P x,P y) {return P(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);}
19 }a[Maxn],b[Maxn];
20
21 char ss[Maxn];
22 int ans[Maxn];
23
24 void fft(P *s,int n,int f)
25 {
26     if(n==1) return;
27     P a0[n>>1],a1[n>>1];
28     for(int i=0;i<=n;i+=2) a0[i>>1]=s[i],a1[i>>1]=s[i+1];
29     fft(a0,n>>1,f);fft(a1,n>>1,f);
30     P wn(cos(2*pi/n),f*sin(2*pi/n)),w(1,0);
31     for(int i=0;i<(n>>1);i++,w=w*wn) s[i]=a0[i]+w*a1[i],s[i+(n>>1)]=a0[i]-w*a1[i];
32 }
33
34 int main()
35 {
36     int n;
37     scanf("%d",&n);n--;
38     scanf("%s",ss);
39     for(int i=0;i<=n;i++) a[n-i].x=(ss[i]-'0');
40     scanf("%s",ss);
41     for(int i=0;i<=n;i++) b[n-i].x=(ss[i]-'0');
42     int nn=1;
43     while(nn<=2*n) nn<<=1;
44     fft(a,nn,1);fft(b,nn,1);
45     for(int i=0;i<=nn;i++) a[i]=a[i]*b[i];
46     fft(a,nn,-1);
47     memset(ans,0,sizeof(ans));
48     for(int i=0;i<=2*n;i++) ans[i]=(int)(a[i].x/nn+0.5);
49     for(int i=0;i<=2*n;i++) ans[i+1]+=ans[i]/10,ans[i]%=10;
50     int ll=2*n;
51     while(ans[ll+1]!=0) ans[ll+2]+=ans[ll+1]/10,ans[++ll]%=10;
52     while(ll>1&&ans[ll]==0) ll--;
53     for(int i=ll;i>=0;i--) printf("%d",ans[i]);//printf("\n");
54     return 0;
55 }
View Code

2017-04-14 11:52:12

posted @ 2017-04-13 09:44  konjak魔芋  阅读(112)  评论(0编辑  收藏  举报