BZOJ 2194: 快速傅立叶之二【FFT】
2194: 快速傅立叶之二
【题目描述】
传送门
【题解】
先将B数组翻转,然后套一下FFT的板子就好了。
代码如下
#include<cstdio>
#include<cmath>
#include<cctype>
#include<complex>
#define CP complex<double>
#define MAXN 400005
using namespace std;
const double PI=acos(-1.0);
int n,rev[MAXN];
CP a[MAXN],b[MAXN];
int read(){
int ret=0;char ch=getchar();bool f=1;
for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-');
for(; isdigit(ch);ch=getchar()) ret=(ret<<3)+(ret<<1)+ch-48;
return f?ret:-ret;
}
void Get_rev(int bit){
for(int i=0;i<(1<<bit);i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
}
void FFT(CP *a,int Len,int dft){
for(int i=0;i<Len;i++)
if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int step=1;step<Len;step<<=1){
CP WN=exp(CP(0,dft*PI/step));
for(int j=0;j<Len;j+=(step<<1)){
CP WNK(1,0);
for(int k=j;k<j+step;k++){
CP x=a[k],y=WNK*a[k+step];
a[k]=x+y,a[k+step]=x-y;WNK*=WN;
}
}
}
if(dft==-1) for(int i=0;i<Len;i++) a[i]/=Len;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("2194.in","r",stdin);
freopen("2194.out","w",stdout);
#endif
n=read();
for(int i=0;i<n;i++) a[i]=read(),b[n-i-1]=read();
int Len=2,bit=1;
for(;(1<<bit)<2*n-1;bit++) Len<<=1;
Get_rev(bit);FFT(a,Len,1);FFT(b,Len,1);
for(int i=0;i<Len;i++) a[i]*=b[i];
FFT(a,Len,-1);
for(int i=0;i<n;i++) printf("%d\n",(int)(a[n+i-1].real()+0.5));
return 0;
}