BZOJ 2179: FFT快速傅立叶 && 洛谷 1919 【模板】A*B Problem升级版(FFT快速傅里叶)【FFT】
BZOJ 2179: FFT快速傅立叶&&洛谷 1919 【模板】A*B Problem升级版(FFT快速傅里叶)
【题目描述】
传送门
【题解】
FFT的板子题。
代码如下
#include<cstdio>
#include<cmath>
#include<complex>
#include<algorithm>
#define MAXN 2094160
#define CP complex<double>
using namespace std;
const double PI=acos(-1.0);
int n,rev[MAXN],Ans[MAXN];
CP a[MAXN],b[MAXN];
char s1[MAXN],s2[MAXN];
void getrev(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("prob.in","r",stdin);
freopen("prob.out","w",stdout);
#endif
scanf("%d%s%s",&n,s1,s2);
int bit=1,Len=2;
for(bit=1;(1<<bit)<2*n-1;bit++) Len<<=1;
for(int i=0;i<n;i++) a[i]=(double)(s1[n-i-1]-'0');
for(int i=0;i<n;i++) b[i]=(double)(s2[n-i-1]-'0');
getrev(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<Len;i++){
Ans[i]+=(int)(a[i].real()+0.5);
Ans[i+1]+=Ans[i]/10;
Ans[i]%=10;
}
int i=n*2;
while(!Ans[i]&&i>=0) i--;
if(i==-1) printf("0");
for(;i>=0;i--) printf("%d",Ans[i]);
printf("\n");
return 0;
}