Code[VS] 3123 高精度练习之超大整数乘法

时间:2023-03-08 16:09:35
Code[VS] 3123 高精度练习之超大整数乘法

FFT 做 高精度乘法

 #include <bits/stdc++.h>

 const double pi = acos(-);

 struct complex
{
double a, b; inline complex(
double _a = ,
double _b = )
{
a = _a;
b = _b;
} inline friend complex operator +
(const complex &a, const complex &b)
{
return complex(a.a + b.a, a.b + b.b);
} inline friend complex operator -
(const complex &a, const complex &b)
{
return complex(a.a - b.a, a.b - b.b);
} inline friend complex operator *
(const complex &a, const complex &b)
{
return complex(a.a*b.a - a.b*b.b, a.a*b.b + a.b*b.a);
} inline friend complex & operator +=
(complex &a, const complex &b)
{
return a = a+b;
} inline friend complex & operator -=
(complex &a, const complex &b)
{
return a = a-b;
} inline friend complex & operator *=
(complex &a, const complex &b)
{
return a = a*b;
}
}; inline complex alpha(double a)
{
return complex(cos(a), sin(a));
} typedef std::vector<complex> vec; vec FFT(const vec &a)
{
int n = a.size(); if (n == )return a; complex w_k(, );
complex w_n = alpha(pi*/n); vec ar[], yr[], y(n); for (int i = ; i < n; ++i)
ar[i & ].push_back(a[i]); for (int i = ; i < ; ++i)
yr[i] = FFT(ar[i]); for (int i = ; i < n/; ++i, w_k *= w_n)
{
y[i] = yr[][i] + w_k * yr[][i];
y[i + n/] = yr[][i] - w_k * yr[][i];
} return y;
} vec IFFT(const vec &a)
{
int n = a.size(); if (n == )return a; complex w_k(, );
complex w_n = alpha(-pi*/n); vec ar[], yr[], y(n); for (int i = ; i < n; ++i)
ar[i & ].push_back(a[i]); for (int i = ; i < ; ++i)
yr[i] = IFFT(ar[i]); for (int i = ; i < n/; ++i, w_k *= w_n)
{
y[i] = yr[][i] + w_k * yr[][i];
y[i + n/] = yr[][i] - w_k * yr[][i];
} return y;
} char s1[]; int len1;
char s2[]; int len2; vec v1, v2, p1, p2, mul, ans; signed main(void)
{
scanf("%s", s1); len1 = strlen(s1);
scanf("%s", s2); len2 = strlen(s2); int len = len1 + len2; while (len != (len&-len))++len; for (int i = len1 - ; ~i; --i)v1.push_back(complex(s1[i] - '', ));
for (int i = len2 - ; ~i; --i)v2.push_back(complex(s2[i] - '', )); while ((int)v1.size() < len)v1.push_back(complex());
while ((int)v2.size() < len)v2.push_back(complex()); p1 = FFT(v1);
p2 = FFT(v2); for (int i = ; i < len; ++i)
mul.push_back(p1[i] * p2[i]); ans = IFFT(mul); std::vector<int> ret; for (int i = ; i < len; ++i)
ret.push_back((int)round(ans[i].a / len)); for (int i = ; i < len; ++i)
if (ret[i] >= )
{
ret[i + ] += ret[i] / ;
ret[i] %= ;
} while (ret.size() != && !ret[ret.size() - ])
ret.pop_back(); for (int i = ret.size() - ; i >= ; --i)
putchar('' + ret[i]);
putchar('\n');
}

@Author: YouSiki