BZOJ 2179 FFT快速傅里叶

Posted on 2016-08-12 09:18  ziliuziliu  阅读(100)  评论(0编辑  收藏  举报

fft。

#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#define maxn 131073
#define pi acos(-1)
using namespace std;
typedef complex<double> E;
int n,m,r[maxn],l=0,c[maxn];
char s[maxn];
E a[maxn],b[maxn];
void fft(E *x,int f)
{
    for (int i=0;i<n;i++)
        if (i<r[i]) swap(x[i],x[r[i]]);
    for (int i=1;i<n;i<<=1)
    {
        E wn(cos(pi/i),f*sin(pi/i));
        for (int j=0;j<n;j+=(i<<1))
        {
            E w(1,0);
            for (int k=0;k<i;k++)
            {
                E r1,r2;
                r1=x[j+k];r2=w*x[i+j+k];
                x[j+k]=r1+r2;x[j+k+i]=r1-r2;
                w*=wn;
            }
        }
    }
    if (f==-1)
    {
        for (int i=0;i<n;i++)
            x[i]/=n;
    }
}
int main()
{
    scanf("%d",&n);n--;
    scanf("%s",s);for (int i=0;i<=n;i++) a[i]=s[n-i]-'0';
    scanf("%s",s);for (int i=0;i<=n;i++) b[i]=s[n-i]-'0';
    m=2*n;
    for (n=1;n<=m;n<<=1) l++;
    for (int i=0;i<n;i++) r[i]=((r[i>>1]>>1)|((i&1)<<(l-1)));
    fft(a,1);fft(b,1);
    for (int i=0;i<n;i++)
        a[i]*=b[i];
    fft(a,-1);
    for (int i=0;i<=m;i++)
        c[i]=(int)(a[i].real()+0.1);
    for (int i=0;i<=m;i++)
    {
        if (c[i]>=10)
        {
            c[i+1]+=c[i]/10;c[i]%=10;
            if (i==m) m++;
        }
    }
    for (int i=m;i>=0;i--) printf("%d",c[i]);
    printf("\n");
    return 0;
}