快速高精度乘法C语言fft,高精度乘法FFT 模板

渣模板,不知为何常数还挺大。。

CODE:

#include

#include

#include

#include

#include

#define MAX 200010

#define PI 3.1415926535897932384626

using namespace std;

struct Complex{

double real,imag;

Complex(double _,double __):real(_),imag(__) {}

Complex() {}

Complex operator +(const Complex &a)const {

return Complex(real + a.real,imag + a.imag);

}

Complex operator -(const Complex &a)const {

return Complex(real - a.real,imag - a.imag);

}

Complex operator *(const Complex &a)const {

return Complex(real * a.real - imag * a.imag,real * a.imag + imag * a.real);

}

void operator *=(const Complex &a) {

*this = *this * a;

}

void Read() {

int temp;

scanf("%1d",&temp);

real = temp;

}

}a[MAX],b[MAX],ans[MAX];

int n;

int out[MAX];

void FFT(Complex x[],int n,int flag)

{

static Complex temp[MAX];

if(n == 1)return ;

for(int i = 0; i < n; i += 2)

temp[i >> 1] = x[i],temp[(i + n) >> 1] = x[i + 1];

memcpy(x,temp,sizeof(Complex) * n);

Complex *l = x,*r = x + (n >> 1);

FFT(l,n >> 1,flag),FFT(r,n >> 1,flag);

Complex unit(cos(flag * 2 * PI / n),sin(flag * 2 * PI / n)),w(1.0,.0);

for(int i = 0; i < (n >> 1); ++i,w *= unit)

temp[i] = l[i] + w * r[i],temp[i + (n >> 1)] = l[i] - w * r[i];

memcpy(x,temp,sizeof(Complex) * n);

}

char s1[MAX],s2[MAX];

int l1,l2;

int main()

{

bool flag = false;

char c;

while(c = getchar(),c == '\n' || c == '\r' || c == ' ' || c == '\t');

if(c != '-')ungetc(c,stdin);

elseflag ^= 1;

scanf("%s",s1);

while(c = getchar(),c == '\n' || c == '\r' || c == ' ' || c == '\t');

if(c != '-')ungetc(c,stdin);

elseflag ^= 1;

scanf("%s",s2);

l1 = strlen(s1),l2 = strlen(s2);

for(int i = l1 - 1,pos = 0; ~i; --i)

a[pos++].real = s1[i] - '0';

for(int i = l2 - 1,pos = 0; ~i; --i)

b[pos++].real = s2[i] - '0';

if((l1 == 1 && s1[0] == '0') || (l2 == 1 && s2[0] == '0')) {

puts("0");

return 0;

}

int l;

for(l = 1; l <= l1 + l2; l <<= 1);

FFT(a,l,1),FFT(b,l,1);

for(int i = 0; i < l; ++i)

ans[i] = a[i] * b[i];

FFT(ans,l,-1);

for(int i = 0; i < l; ++i)

out[i] = int(ans[i].real / l + .5);

int temp = 0;

for(int i = 0; i < l; ++i) {

out[i] += temp;

temp = out[i] / 10;

out[i] %= 10;

}

while(temp)out[l++] = temp % 10,temp /= 10;

while(!out[l - 1])--l;

if(flag)putchar('-');

for(int i = l - 1; ~i; --i)

printf("%d",out[i]);

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值