@@ -216,13 +216,15 @@ namespace cp_algo::math::fft {
216
216
217
217
template <modint_type base>
218
218
struct dft <base> {
219
- static constexpr int split = 1 << 15 ;
219
+ int split;
220
220
cvector A, B;
221
221
222
222
dft (std::vector<base> const & a, size_t n): A(n), B(n) {
223
+ split = std::sqrt (base::mod ());
223
224
cvector::exec_on_roots (2 * n, size (a), [&](size_t i, point rt) {
224
- A.set (i % n, A.get (i % n) + ftype (a[i].rem () % split) * rt);
225
- B.set (i % n, B.get (i % n) + ftype (a[i].rem () / split) * rt);
225
+ size_t ti = std::min (i, i - n);
226
+ A.set (ti, A.get (ti) + ftype (a[i].rem () % split) * rt);
227
+ B.set (ti, B.get (ti) + ftype (a[i].rem () / split) * rt);
226
228
227
229
});
228
230
if (n) {
@@ -248,19 +250,20 @@ namespace cp_algo::math::fft {
248
250
B.ifft ();
249
251
C.ifft ();
250
252
res.resize (2 * n);
253
+ auto splitsplit = (base (split) * split).rem ();
251
254
cvector::exec_on_roots (2 * n, n, [&](size_t i, point rt) {
252
255
rt = conj (rt);
253
256
auto Ai = A.get (i) * rt;
254
257
auto Bi = B.get (i) * rt;
255
258
auto Ci = C.get (i) * rt;
256
- base A0 = llround (real (Ai));
257
- base A1 = llround (real (Ci));
258
- base A2 = llround (real (Bi));
259
- res[i] = A0 + A1 * split + A2 * split * split ;
260
- base B0 = llround (imag (Ai));
261
- base B1 = llround (imag (Ci));
262
- base B2 = llround (imag (Bi));
263
- res[n + i] = B0 + B1 * split + B2 * split * split ;
259
+ int64_t A0 = llround (real (Ai));
260
+ int64_t A1 = llround (real (Ci));
261
+ int64_t A2 = llround (real (Bi));
262
+ res[i] = A0 + A1 * split + A2 * splitsplit ;
263
+ int64_t B0 = llround (imag (Ai));
264
+ int64_t B1 = llround (imag (Ci));
265
+ int64_t B2 = llround (imag (Bi));
266
+ res[n + i] = B0 + B1 * split + B2 * splitsplit ;
264
267
});
265
268
}
266
269
void mul (auto &&B, auto & res) {
0 commit comments