Skip to content

Commit 43813c2

Browse files
committed
Long multiplication for small m
1 parent 64a2510 commit 43813c2

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

cp-algo/math/bigint.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,33 @@ namespace cp_algo::math {
283283
if (m <= 1) {
284284
return *this *= int64_t(m == 0 ? 0 : other.digits[0]);
285285
}
286+
// Small m: use schoolbook long multiplication in base `Base`
287+
// Threshold chosen empirically to avoid FFT overhead on small sizes
288+
constexpr size_t SMALL_M_THRESHOLD = 32;
289+
if (m <= SMALL_M_THRESHOLD) {
290+
big_basic_string<uint64_t> res;
291+
res.assign(n + m, 0);
292+
for (size_t i = 0; i < n; i++) {
293+
if (digits[i] == 0) continue;
294+
uint64_t carry = 0;
295+
for (size_t j = 0; j < m; j++) {
296+
__uint128_t cur = res[i + j]
297+
+ (__uint128_t)digits[i] * other.digits[j]
298+
+ carry;
299+
res[i + j] = uint64_t(cur % Base);
300+
carry = uint64_t(cur / Base);
301+
}
302+
size_t k = i + m;
303+
if (carry) {
304+
uint64_t cur = res[k] + carry;
305+
res[k] = cur % Base;
306+
carry = cur / Base;
307+
k++;
308+
}
309+
}
310+
digits = std::move(res);
311+
return normalize();
312+
}
286313
to_metabase();
287314
other.to_metabase();
288315
fft::conv_simple(digits, other.digits);

0 commit comments

Comments
 (0)