2194: 快速傅立叶之二
需要一点点小变化,题目中的所求并不是卷积的形式,但是我们发现,如果将其中一个数组倒序读入,那么原题中的式子又会变成卷积的形式,C[k]对应卷积后的a[n-1+k]项。
1 #include<bits/stdc++.h> 2 #define pi acos(-1) 3 using namespace std; 4 const int inf=4e5+10; 5 int n; 6 struct cp{ 7 double x,y; 8 cp operator * (const cp &o)const{ 9 return (cp){x*o.x-y*o.y,x*o.y+y*o.x}; 10 } 11 cp operator + (const cp &o)const{ 12 return (cp){x+o.x,y+o.y}; 13 } 14 cp operator - (const cp &o)const{ 15 return (cp){x-o.x,y-o.y}; 16 } 17 }a[inf],b[inf]; 18 int r[inf]; 19 void fft(cp *a,int l,int type){ 20 for(int i=0;i<l;i++) 21 if(i<r[i])swap(a[i],a[r[i]]); 22 for(int i=2;i<=l;i<<=1){ 23 cp wn=(cp){cos(2*pi/i),sin(2*pi*type/i)}; 24 for(int j=0;j<l;j+=i){ 25 cp w=(cp){1,0}; 26 for(int k=j;k<j+i/2;k++,w=w*wn){ 27 cp u=a[k],v=a[k+i/2]*w; 28 a[k]=u+v;a[k+i/2]=u-v; 29 } 30 } 31 } 32 } 33 int main() 34 { 35 scanf("%d",&n); 36 for(int i=0;i<n;i++){ 37 scanf("%lf",&a[i].x); 38 scanf("%lf",&b[n-i-1].x); 39 } 40 int l=1,h=0; 41 while(l<n*2-1)l<<=1,h++; 42 for(int i=1;i<l;i++) 43 r[i]=(r[i>>1]>>1)+((i&1)<<(h-1)); 44 fft(a,l,1);fft(b,l,1); 45 for(int i=0;i<l;i++)a[i]=a[i]*b[i]; 46 fft(a,l,-1); 47 for(int i=n-1;i<2*n-1;i++)printf("%d\n",(int)(a[i].x/l+0.5)); 48 return 0; 49 }