hdu 1402-傅里叶_大数相乘

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

const double PI = acos(-1.0);
struct complex{
    double real,img;
    complex(double _real = 0,double _img = 0){
        real = _real; img = _img;
    }
};
complex operator +(const complex &a,const complex &b){
    return complex(a.real+b.real,a.img+b.img);
}
complex operator -(const complex &a,const complex &b){
    return complex(a.real-b.real,a.img-b.img);
}
complex operator *(const complex &a,const complex &b){
    return complex(a.real*b.real-a.img*b.img,a.real*b.img+a.img*b.real);
}
void change(complex y[],int len){
    int i,j,k;
    for(i=1,j=len/2;i<len-1;i++){
        if(i<j) swap(y[i],y[j]);k=len/2;
        while(j>=k) j-=k,k/=2; if(j<k)j+=k;
    }
}
void FFT(complex y[],int len,int on){
    change(y,len);
    complex t,u;
    for(int h=2;h<=len;h<<=1){
        complex wn(cos(on*2*PI/h),sin(on*2*PI/h));
        for(int j=0;j<len;j+=h){
            complex w(1,0);
            for(int k=j;k<j+h/2;k++){
                u=y[k]; t=w*y[k+h/2];
                y[k]=u+t; y[k+h/2]=u-t;
                w=w*wn;
            }
        }
    }
    if(on==-1) for(int i=0;i<len;i++) y[i].real/=len;
}

#define N 300000
complex x1[N],x2[N];
void cal(char x[],int n,char y[],int m){
    int i,c,L=max(n,m);
    for(i=0;i<n/2;i++) swap(x[i],x[n-1-i]);
    for(i=0;i<m/2;i++) swap(y[i],y[m-1-i]);
    for(i=1;i<2*L;i*=2); L=i;
    for(i=0;i<n;i++) x1[i].real=x[i]-'0',x1[i].img=0;
    for(;i<L;i++)x1[i].real=x1[i].img=0;
    for(i=0;i<m;i++) x2[i].real=y[i]-'0',x2[i].img=0;
    for(;i<L;i++)x2[i].real=x2[i].img=0;
    FFT(x1,L,1);FFT(x2,L,1);
    for(i=0;i<L;i++)x1[i]=x1[i]*x2[i];
    FFT(x1,L,-1);
    for(i=c=n=0;i<L;i++){
        c+=x1[i].real+0.5;
        x[i]=c%10+'0';if(c)n=i;
        c/=10;
    }
    if(c)x[++n]=c;x[++n]=0;
    for(i=0;i<n/2;i++) swap(x[i],x[n-1-i]);
}

char a[N],b[N];
int main(){
    while(scanf("%s%s",a,b)!=EOF){
        cal(a,strlen(a),b,strlen(b));
        printf("%s\n",a);
    }
    return 0;
}


多项式相乘整数运算版(效率较上面的提高了几倍):

 

#define CARRY 10000
#define CARRY_LEN 4
void cal(int x[],int &n,int y[],int m){
	int i,L=max(n,m)*2;
	for(i=1;i<L;i<<=1); L=i;
	for(i=0;i<n;++i) x1[i].real=x[i],x1[i].img=0;
	for(;i<L;i++)x1[i].real=x1[i].img=0;
	for(i=0;i<m;++i) x2[i].real=y[i],x2[i].img=0;
	for(;i<L;++i) x2[i].real=x2[i].img=0;
	FFT(x1,L,1);FFT(x2,L,1);
	for(i=0;i<L;++i)x1[i]=x1[i]*x2[i];
	FFT(x1,L,-1);
	long long c=0;
	for(i=n=0;i<L;++i){
		c+=x1[i].real+0.5;
		x[i]=c%CARRY;if(c) n=i;
		c/=CARRY;
	}
	if(c) x[++n]=c; ++n;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值