颓了那么多天开始做题目。。
今天又去看了一下FFT 总算是全部搞懂了。。
Rader很神啊
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<complex>
using namespace std;
#define com complex<double>
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
inline void Get(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
a=c-'0';
}
int St[1000001];
int N;
struct Complex_Line
{
int n;
com *Line;
inline void Begin(int t){Line=new com[n=t];}
inline void print()
{
for(int i=0;i<n;i++)
St[i]=(Line[i].real()+0.1);
St[n]=0;
int len=n;
if(St[len+1])len++;
while(!St[len])len--;
for(int i=N-1;i!=-1;i--)
printf("%d\n",St[i]);
}
};
const
double pi=acos(-1);
int rev[1000001];
inline void Beg(int Len)
{
int L=0,t=1;
while((1<<L)^Len)L++;
for(int i=0;i<Len;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
}
inline Complex_Line Rev(Complex_Line a)
{
Complex_Line Re;
Re.Begin(a.n);
for(int i=0;i<a.n;i++)
Re.Line[rev[i]]=a.Line[i];
return Re;
}
inline Complex_Line FFT(Complex_Line t,int f)
{
int n=t.n;
Complex_Line A=Rev(t);
for(int i=1;i<n;i<<=1)
{
com W0=com(cos(pi/i),f*sin(pi/i));
for(int j=0;j<n;j+=(i<<1))
{
com W(1,0);
for(int k=0;k<i;k++)
{
com x=A.Line[j+k],y=W*A.Line[j+k+i];
A.Line[j+k]=x+y;
A.Line[j+k+i]=x-y;
W*=W0;
}
}
}
if(f==-1)
for(int j=0;j<n;j++)
A.Line[j]/=n;
return A;
}
int main()
{
int n;
read(n); N=n;
int tp=n;
while(tp^(tp&-tp))
{
tp^=tp&-tp;
}
tp<<=2;
int i;
Complex_Line A,B;
A.Begin(tp);
B.Begin(tp);
int j;
for(i=1;i<=n;i++)
{
read(j);
A.Line[n-i]=j;
read(j);
B.Line[i-1]=j;
}
for(i=n;i<tp;i++)
A.Line[i]=com(0,0),
B.Line[i]=com(0,0);
Beg(tp);
A=FFT(A,1);
B=FFT(B,1);
for(i=0;i<tp;i++)
A.Line[i]=A.Line[i]*B.Line[i];
A=FFT(A,-1);
A.print();
return 0;
}