Submit: 1147 Solved: 658
Description
请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。
Input
第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[i],b[i] (0 < = i < N)。
Output
输出N行,每行一个整数,第i行输出C[i-1]。
Sample Input
5
3 1
2 4
1 1
2 4
1 4
3 1
2 4
1 1
2 4
1 4
Sample Output
24
12
10
6
1
12
10
6
1
HINT
Source
把b[]数组逆序,则sigma内下标和为定值,可以套用FFT
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<complex> 6 #define pi acos(-1) 7 using namespace std; 8 const int mxn=100010*3; 9 typedef complex<double>com; 10 com a[mxn],b[mxn]; 11 int rev[mxn]; 12 int n,l; 13 void FFT(com* a,int flag){ 14 int i,j,x; 15 for(i=0;i<n;i++) 16 if(rev[i]>i)swap(a[rev[i]],a[i]); 17 for(i=1;i<n;i<<=1){ 18 com wn(cos(pi/i),flag*sin(pi/i)); 19 for(j=0;j<n;j+=(i<<1)){ 20 com w(1,0); 21 for(int k=0;k<i;k++,w*=wn){ 22 com x=a[j+k],y=w*a[i+j+k]; 23 a[j+k]=x+y; 24 a[i+j+k]=x-y; 25 } 26 } 27 } 28 if(flag==-1)for(i=0;i<n;i++)a[i]/=n; 29 } 30 int main(){ 31 int i,j; 32 scanf("%d",&n); 33 for(i=0;i<n;i++)scanf("%lf%lf",&a[i],&b[n-i-1]); 34 int m=n<<1; 35 for(n=1;n<m;n<<=1)l++; 36 for(i=0;i<n;i++){ 37 rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1)); 38 } 39 FFT(a,1);FFT(b,1); 40 for(i=0;i<n;i++)a[i]*=b[i]; 41 FFT(a,-1); 42 m>>=1; 43 for(i=m-1;i<2*m-1;i++) 44 printf("%d\n",(int)(a[i].real()+0.5)); 45 return 0; 46 }