[BZOJ 2194] Fast Fourier second, bzoj2194 Fourier
2194: Fast Fourier second
Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 430 Solved: 240
[Submit] [Status] [Discuss]
Description
Calculate C [k] = sigma (a [I] * B [I-k]), where k <= I <n and n <= 10 ^ 5. All elements in a and B are non-negative integers less than or equal to 100.
Input
The first line is an integer N, And the next N rows are I + 2 .. I + N-1 line, two numbers in each row, in turn represents a [I], B [I] (0 <= I <N ).
Output
Output N rows, each row has an integer, and the I rows Output C [I-1].
Sample Input
5
3 1
2 4
1 1
2 4
1 4
Sample Output
24
12
10
6
1
FFT template question.
For more information about FFT, see [BZOJ 2179]
FFT calculates the product of two polynomials whose subscript is a fixed value, and the difference in this question is a fixed value. We only need to reverse the order of the [] array to the sum value!
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <complex>#define N 500005#define pi acos(-1)#define LL long longusing namespace std;int n;complex<double> a[N],b[N],p[N];void read(int &tmp){ tmp=0; char ch=getchar(); int fu=1; for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') fu=-1; for (;ch>='0'&&ch<='9';ch=getchar()) tmp=tmp*10+ch-'0'; tmp*=fu;}void FFT(complex<double> x[],int n,int p){ for (int i=0,t=0;i<n;i++) { if (i>t) swap(x[i],x[t]); for (int j=n>>1;(t^=j)<j;j>>=1); } for (int m=2;m<=n;m<<=1) { complex<double> wn(cos(p*2*pi/m),sin(p*2*pi/m)); for (int i=0;i<n;i+=m) { complex<double> w(1,0),u; int k=m>>1; for (int j=0;j<k;j++,w*=wn) { u=x[i+j+k]*w; x[i+j+k]=x[i+j]-u; x[i+j]=x[i+j]+u; } } }}int main(){ scanf("%d",&n); for (int i=0;i<n;i++) { int x; read(x); a[n-i-1]=x; read(x); b[i]=x; } int nn=n; for (int j=n,i=1;(i>>1)<j;i<<=1) n=i; cout<<n<<endl; FFT(a,n,1),FFT(b,n,1); for (int i=0;i<n;i++) p[i]=a[i]*b[i]; FFT(p,n,-1); for (int i=nn-1;i>=0;i--) printf("%lld\n",(LL)(p[i].real()/n+0.5)); return 0;}