-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKarac_mul.cpp
42 lines (34 loc) · 1009 Bytes
/
Karac_mul.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "Long.h"
Long Long::karac_mul(const Long & b) const
{
if ((size() < karacnaive && b.size() < karacnaive)) {
return mul(b);
}
auto k = std::max(size(), b.size()) / 2;
if (k * 2 < std::max(size(), b.size()))
k += 1;
if (k == 0)
return mul(b);
int fl = (sign * b.sign);
Long xr(vector<ull>(k, (ull)0));
Long xl(vector<ull>(k, (ull)0));
Long yr(vector<ull>(k, (ull)0));
Long yl(vector<ull>(k, (ull)0));
static auto f = [](Long& wh, const Long& what, int k, int mode) {
if (mode == 1)
mode = k;
for (uint i = mode; i < k + mode && i < what.size(); ++i) {
wh.a[i - mode] = what[i];
}
wh.normal();
};
f(xr, *this, k, 0);
f(yr, b, k, 0);
f(xl, *this, k, 1);
f(yl, b, k, 1);
Long xlyl = xl.karac_mul(yl);
Long xryr = xr.karac_mul(yr);
// Long xxyy = (xl + xr).karac_mul(yl + yr) - (xlyl + xryr);
return (Long().insert(xlyl.a).insert(vector<ull>(2 * k, 0)) + xryr
+ ((xl + xr).karac_mul(yl + yr) - (xlyl + xryr)).insert(vector<ull>(k, 0))).changeSign(fl);
}