@@ -231,11 +231,12 @@ namespace cp_algo::math::fft {
231
231
}
232
232
}
233
233
234
- std::vector<base> mul (auto &&C, auto &&D) {
234
+ void mul (auto &&C, auto &&D, auto &res ) {
235
235
assert (A.size () == C.size ());
236
236
size_t n = A.size ();
237
237
if (!n) {
238
- return std::vector<base>();
238
+ res = {};
239
+ return ;
239
240
}
240
241
for (size_t i = 0 ; i < n; i += flen) {
241
242
auto tmp = A.vget (i) * D.vget (i) + B.vget (i) * C.vget (i);
@@ -246,7 +247,7 @@ namespace cp_algo::math::fft {
246
247
A.ifft ();
247
248
B.ifft ();
248
249
C.ifft ();
249
- std::vector<base> res (2 * n);
250
+ res. resize (2 * n);
250
251
cvector::exec_on_roots (2 * n, n, [&](size_t i, point rt) {
251
252
rt = conj (rt);
252
253
auto Ai = A.get (i) * rt;
@@ -261,10 +262,14 @@ namespace cp_algo::math::fft {
261
262
base B2 = llround (imag (Bi));
262
263
res[n + i] = B0 + B1 * split + B2 * split * split;
263
264
});
264
- return res;
265
+ }
266
+ void mul (auto &&B, auto & res) {
267
+ mul (B.A , B.B , res);
265
268
}
266
269
std::vector<base> operator *= (auto &&B) {
267
- return mul (B.A , B.B );
270
+ std::vector<base> res;
271
+ mul (B.A , B.B , res);
272
+ return res;
268
273
}
269
274
270
275
auto operator * (dft const & B) const {
@@ -290,19 +295,19 @@ namespace cp_algo::math::fft {
290
295
auto n = com_size (a.size (), b.size ());
291
296
auto A = dft<base>(a, n);
292
297
if (a == b) {
293
- a = A *= dft<base>(A);
298
+ A. mul ( dft<base>(A), a );
294
299
} else {
295
- a = A *= dft<base>(b, n);
300
+ A. mul ( dft<base>(b, n), a );
296
301
}
297
302
}
298
303
template <typename base>
299
304
void circular_mul (std::vector<base> &a, std::vector<base> const & b) {
300
305
auto n = std::max (flen, std::bit_ceil (max (a.size (), b.size ())) / 2 );
301
306
auto A = dft<base>(a, n);
302
307
if (a == b) {
303
- a = A *= dft<base>(A);
308
+ A. mul ( dft<base>(A), a );
304
309
} else {
305
- a = A *= dft<base>(b, n);
310
+ A. mul ( dft<base>(b, n), a );
306
311
}
307
312
}
308
313
}
0 commit comments