FFT高精度乘法

裸FFT走一波~~~

#include <cmath>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const double PI=acos(-1.0);
char s1[100005];
char s2[100005];
int ans[200005];
struct Complex
{
	double real,ima;
	Complex(double r=0.0,double i=0.0): real(r),ima(i){}
	Complex operator + (Complex &b)const
	{
		return Complex(real+b.real,ima+b.ima);
	}
	Complex operator - (Complex &b)const
	{
		return Complex(real-b.real,ima-b.ima);
	}
	Complex operator * (Complex &b)const
	{
		return Complex(real*b.real-ima*b.ima,real*b.ima+ima*b.real);
	}
};
Complex a[200005];
Complex b[200005];
Complex c[200005];
void rader(Complex* a,int len)
{
	int j=len>>1;
	for(int i=1;i<len-1;i++)
	{
		if(i<j)swap(a[i],a[j]);
		int k=len>>1;
		while(j>=k)
		{
			j-=k;
			k>>=1;
		}
		if(j<k)j+=k;
	}
}
void fft(Complex* a,int len,int on)
{
	rader(a,len);
	for(int ll=2;ll<=len;ll*=2)
	{
		double ang=on*2*PI/ll;
		Complex wn(cos(ang),sin(ang));
		for(int i=0;i<len;i+=ll)
		{
			Complex w(1.0,0.0);
			for(int j=i;j<i+ll/2;j++)
			{
				Complex u=a[j];
				Complex t=w*a[j+ll/2];
				a[j]=u+t;
				a[j+ll/2]=u-t;
				w=w*wn;
			}
		}
	}
	if(on==-1)
	{
		for(int i=0;i<len;i++)
		a[i].real/=len;
	}
}
int main()
{
	scanf("%s%s",s1,s2);
	int lena=strlen(s1);
	int lenb=strlen(s2);
	int len=1;
	while(len<2*lena||len<2*lenb)len*=2;
	int o=0;
	for(o=0;o<lena;o++)
	{
	a[o].real=s1[lena-o-1]-'0';
	a[o].ima=0.0;	
	}
	while(o<len)
	{
	a[o].real=0;	
	a[o].ima=0;	
	o++;
	}
	for(o=0;o<lenb;o++)
	{
	b[o].real=s2[lenb-o-1]-'0';
	b[o].ima=0.0;	
	}
	while(o<len)
	{
	b[o].real=0;	
	b[o].ima=0;
	o++;
	}
	fft(a,len,1);
	fft(b,len,1);
	for(int i=0;i<len;i++)
	c[i]=a[i]*b[i];
	fft(c,len,-1);
	for(int i=0;i<len;i++)
	ans[i]=int(c[i].real+0.5);
	for(int i=0;i<len;i++)
	{
		ans[i+1]+=ans[i]/10;
		ans[i]%=10;
	}
	int high;
	for(int i=len-1;i>=0;i--)
	{
		if(ans[i])
		{
			high=i;
			break;
		}
	}
	for(int i=high;i>=0;i--)
	printf("%d",ans[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/richard__luan/article/details/80942348