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

【FFT】hdu1402 A * B Problem Plus

时间:2017-03-30 00:05:09      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:include   double   turn   names   strlen   dft   fft   amp   ret   

FFT板子。

将大整数看作多项式,它们的乘积即多项式的乘积在x=10处的取值。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define EPS 1e-8
const double PI = acos(-1.0);
struct Complex{
	double real,image;
	Complex(double _real,double _image){
		real=_real;
		image=_image;
	}
	Complex(){}
};
Complex operator + (const Complex &c1,const Complex &c2){
	return Complex(c1.real+c2.real,c1.image+c2.image);
}
Complex operator - (const Complex &c1,const Complex &c2){
	return Complex(c1.real-c2.real,c1.image-c2.image);
}
Complex operator * (const Complex &c1,const Complex &c2){
	return Complex(c1.real*c2.real-c1.image*c2.image,c1.real*c2.image+c1.image*c2.real);
}
int rev(int id,int len){
    int ret=0;
    for(int i=0;(1<<i)<len;++i){
		ret<<=1;
		if(id&(1<<i)){
			ret|=1;
		}
	}
	return ret;
}
Complex tmp[200100];
//μ±DFT==1ê±ê?DFT, DFT==-1ê±?òê???DFT
void IterativeFFT(Complex A[],int len, int DFT){//??3¤?è?alen(2μ??Y)μ?êy×é??DDDFT±???
	for(int i=0;i<len;++i){
		tmp[rev(i,len)]=A[i];
	}
	for(int i=0;i<len;++i){
		A[i]=tmp[i];
	}
	for(int s=1;(1<<s)<=len;++s){
		int m=(1<<s);
		Complex wm=Complex(cos(DFT*2*PI/m),sin(DFT*2*PI/m));
		for(int k=0;k<len;k+=m){//?aò?2??áμ?°üo?μ?êy×é?a????êy??ê?(1<<s)
			Complex w=Complex(1,0);
			for(int j=0;j<(m>>1);++j){//??°?òyàí£??ù?Yá???×ó?úμ????????úμ?
				Complex t=w*A[k+j+(m>>1)];
				Complex u=A[k+j];
				A[k+j]=u+t;
				A[k+j+(m>>1)]=u-t;
				w=w*wm;
			}
		}
	}
	if(DFT==-1){
		for(int i=0;i<len;++i){
			A[i].real/=len;
			A[i].image/=len;
		}
	}
}
Complex a[200100],b[200100];
int ans[200100];
char s1[50010],s2[50010];
int main(){
//	freopen("a.in","r",stdin);
	while(scanf("%s%s",s1,s2)!=EOF){
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(ans,0,sizeof(ans));
		int len1=strlen(s1),len2=strlen(s2),len;
		if((len1==1 && s1[0]==‘0‘) || (len2==1 && s2[0]==‘0‘)){
			puts("0");
			continue;
		}
		for(int i=0;;++i){
			if((1<<i)>=len1+len2){
				len=(1<<i);
				break;
			}
		}
		for(int i=len1-1,j=0;i>=0;--i,++j){
			a[j]=Complex(s1[i]-‘0‘,0);
		}
		for(int i=len2-1,j=0;i>=0;--i,++j){
			b[j]=Complex(s2[i]-‘0‘,0);
		}
		IterativeFFT(a,len,1);
		IterativeFFT(b,len,1);
		for(int i=0;i<len;++i){
			a[i]=a[i]*b[i];
		}
		IterativeFFT(a,len,-1);
		for(int i=0;i<len;++i){
			ans[i]=(int)(a[i].real+0.5);
		}
		for(int i=0;i<len1+len2-1;++i){
			ans[i+1]+=ans[i]/10;
			ans[i]%=10;
		}
		for(int i=len;i>=0;--i){
			if(ans[i]!=0){
				for(int j=i;j>=0;--j){
					printf("%d",ans[j]);
				}
				puts("");
				break;
			}
		}
	}
	return 0;
}

【FFT】hdu1402 A * B Problem Plus

标签:include   double   turn   names   strlen   dft   fft   amp   ret   

原文地址:http://www.cnblogs.com/autsky-jadek/p/6642449.html

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