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;
}
posted @ 2018-07-02 21:21  XSamsara  阅读(93)  评论(0编辑  收藏  举报