码迷,mamicode.com
首页 > 其他好文 > 详细

spoj VFMUL FFT快速傅立叶变换模板题

时间:2014-12-18 13:21:44      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:style   blog   ar   io   color   os   sp   for   on   

  题意;求两个数相乘。

  第一次写非递归的fft,因为一个数组开小了调了两天TAT。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
#define PI 3.1415926535897932384
#define MAXN 1200000
#pragma optimize("O2")
struct Complex
{
        double x,y;
        Complex(){};
        Complex(double x,double y):x(x),y(y){};
        void init(double x,double y)
        {
                this->x=x;this->y=y;
        }
        Complex operator +(Complex a)
        {
                Complex ret(x + a.x, y + a.y);
                return ret;
        }
        Complex operator -(Complex a)
        {
                Complex ret(x - a.x, y - a.y);
                return ret;
        }
        Complex operator *(Complex a)
        {
                Complex ret(x*a.x - y*a.y, x*a.y + y*a.x);
                return ret;
        }
        Complex operator /(double v)
        {
                Complex ret(x/v,y/v);
                return ret;
        }
        Complex operator =(double x)
        {
                this->x=x;
                return *this;
        }
        void operator -=(Complex a)
        {
                this->x-=a.x;
                this->y-=a.y;
        }
        void operator +=(Complex a)
        {
                this->x+=a.x;
                this->y+=a.y;
        }
};
char ss[MAXN];
int t1[MAXN],t2[MAXN];
int pp[MAXN];
Complex ww[MAXN][2];
Complex g1[MAXN],g2[MAXN];
long long res[MAXN];
int n;
void dft(Complex g[],int len,int sign)
{
        Complex t;
        for (int i=1;i<len;i<<=1)
        {
                for (int j=0;j<len;j+=(i<<1))
                {
                        for (int k=0;k<i;k++)
                        {
                                t=g[j+k];
                                g[j+k]=g[j+k]+g[j+k+i]*ww[k*((n>>1)/i)][sign];
                                g[j+k+i]=t-g[j+k+i]*ww[k*((n>>1)/i)][sign];
                        }
                }
        }
}

int main()
{
        freopen("input.txt","r",stdin);
        //    freopen("output.txt","w",stdout);
        int i,j,k,x,y,z,m;
        int n1,n2;
        int nn;
        scanf("%d",&nn);
        while (nn--)
        {

                scanf("%s",ss);
                m=strlen(ss);
                for (i=0;i<m;i++)
                        t1[(m-i-1)/5]=t1[(m-i-1)/5]*10+ss[i]-0;
                n1=(m-1)/5+1;
                scanf("%s",ss);
                m=strlen(ss);
                for (i=0;i<m;i++)
                        t2[(m-i-1)/5]=t2[(m-i-1)/5]*10+ss[i]-0;
                n2=(m-1)/5+1;
                n=max(n1,n2);
                while (n!=(n&(-n)))n-=n&(-n);
                n<<=2;
                for (i=0;i<n;i++)
                        for (j=n>>1,x=1;j;j>>=1,x<<=1)
                                if (i&j)pp[i]+=x;
                for (i=0;i<n1;i++)g1[pp[i]].x=t1[i];
                for (i=0;i<n2;i++)g2[pp[i]].x=t2[i];
                for (i=0;i<=n;i++)
                {
                        ww[i][0].init(cos(2*PI*i/n), -sin(2*PI*i/n));
                        ww[i][1].x=ww[i][0].x;
                        ww[i][1].y=-ww[i][0].y;
                }
                dft(g1,n,0);
                dft(g2,n,0);
                for (i=0;i<n;i++)g2[i]=g1[i]*g2[i];
                for (i=0;i<n;i++)g1[pp[i]]=g2[i];
                dft(g1,n,1);
                for (i=0;i<n;i++)res[i]=(long long)(g1[i].x/n+0.5);
                for (i=0;i<n;i++)res[i+1]+=res[i]/100000,res[i]%=100000;
                m=n;
                while (m && !res[m-1])m--;
                printf("%d",(int)res[m-1]);
                for (i=m-2;i>=0;i--)
                        printf("%05d",(int)res[i]);
                printf("\n");
                memset(t1,0,sizeof(t1[0])*n);
                memset(t2,0,sizeof(t2[0])*n);
                memset(pp,0,sizeof(pp[0])*n);
                memset(res,0,sizeof(res[0])*n);
                memset(g1,0,sizeof(g1[0])*n);
                memset(g2,0,sizeof(g2[0])*n);
        }
}

 

spoj VFMUL FFT快速傅立叶变换模板题

标签:style   blog   ar   io   color   os   sp   for   on   

原文地址:http://www.cnblogs.com/mhy12345/p/4171455.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!