【BZOJ】【2194】快速傅里叶之二

FFT

  c[k]=sigma a[i]*b[i-k] 这个形式不好搞……

  而我们熟悉的卷积的形式是这样的 c[k]=sigma a[i]*b[k-i]也就是【下标之和是定值】

  所以我们将a数组反转一下就可以卷积了=。=

 1 /**************************************************************
 2     Problem: 2194
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:2008 ms
 7     Memory:48148 kb
 8 ****************************************************************/
 9  
10 //BZOJ 2194
11 #include<cmath>
12 #include<cstdio>
13 #include<cstring>
14 #include<cstdlib>
15 #include<iostream>
16 #include<algorithm>
17 #define rep(i,n) for(int i=0;i<n;++i)
18 #define F(i,j,n) for(int i=j;i<=n;++i)
19 #define D(i,j,n) for(int i=j;i>=n;--i)
20 using namespace std;
21 int getint(){
22     int v=0,sign=1; char ch=getchar();
23     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
24     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
25     return v*sign;
26 }
27 /*******************template********************/
28 const int N=1000010;
29 const double pi=acos(-1);
30 struct comp{
31     double r,i;
32 //  comp(){}
33     comp(double _=0.0,double __=0.0) : r(_),i(__){}
34     comp operator + (const comp &b)const{return comp(r+b.r,i+b.i);}
35     comp operator - (const comp &b)const{return comp(r-b.r,i-b.i);}
36     comp operator * (const comp &b)const{return comp(r*b.r-i*b.i,r*b.i+i*b.r);}
37 }a[N],b[N],c[N];
38 void FFT(comp *a,int n,int type){
39     for(int i=1,j=0;i<n-1;++i){
40         for(int s=n;j^=s>>=1,~j&s;);
41         if(i<j) swap(a[i],a[j]);
42     }
43     for(int m=1;m<n;m<<=1){
44         double u=pi/m*type; comp wm(cos(u),sin(u));
45         for(int i=0;i<n;i+=(m<<1)){
46             comp w(1,0);
47             rep(j,m){
48                 comp &A=a[i+j+m], &B=a[i+j], t=w*A;
49                 A=B-t; B=B+t; w=w*wm;
50             }
51         }
52     }
53     if (type==-1) rep(i,n) a[i].r/=n;
54 }
55   
56 int main(){
57     int n=getint();
58     rep(i,n){
59         a[n-i-1].r=getint();
60         b[i].r=getint();
61     }
62     int len=1;
63     for(len=1;len<=n<<1;len<<=1);
64     FFT(a,len,1); FFT(b,len,1);
65     rep(i,len) c[i]=a[i]*b[i];
66     FFT(c,len,-1);
67     D(i,n-1,0) printf("%d\n",int(c[i].r+0.5) );
68     return 0;
69 }
View Code

 

posted @ 2015-02-06 17:30  Tunix  阅读(160)  评论(0编辑  收藏  举报