From b76ba519ca3d40cc961b37fbcbb5731ac83e714f Mon Sep 17 00:00:00 2001 From: Kohei Morita Date: Sun, 26 Mar 2023 15:37:56 +0900 Subject: [PATCH 1/2] fix convolution constraint --- atcoder/convolution.hpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/atcoder/convolution.hpp b/atcoder/convolution.hpp index 7b27f81..059b5c6 100644 --- a/atcoder/convolution.hpp +++ b/atcoder/convolution.hpp @@ -199,7 +199,6 @@ template * = nullptr> std::vector convolution_fft(std::vector a, std::vector b) { int n = int(a.size()), m = int(b.size()); int z = (int)internal::bit_ceil((unsigned int)(n + m - 1)); - assert(mint::mod() % z == 1); a.resize(z); internal::butterfly(a); b.resize(z); @@ -220,6 +219,10 @@ template * = nullptr> std::vector convolution(std::vector&& a, std::vector&& b) { int n = int(a.size()), m = int(b.size()); if (!n || !m) return {}; + + int z = (int)internal::bit_ceil((unsigned int)(n + m - 1)); + assert(mint::mod() % z == 1); + if (std::min(n, m) <= 60) return convolution_naive(a, b); return internal::convolution_fft(a, b); } @@ -229,6 +232,10 @@ std::vector convolution(const std::vector& a, const std::vector& b) { int n = int(a.size()), m = int(b.size()); if (!n || !m) return {}; + + int z = (int)internal::bit_ceil((unsigned int)(n + m - 1)); + assert(mint::mod() % z == 1); + if (std::min(n, m) <= 60) return convolution_naive(a, b); return internal::convolution_fft(a, b); } @@ -241,6 +248,10 @@ std::vector convolution(const std::vector& a, const std::vector& b) { if (!n || !m) return {}; using mint = static_modint; + + int z = (int)internal::bit_ceil((unsigned int)(n + m - 1)); + assert(mint::mod() % z == 1); + std::vector a2(n), b2(m); for (int i = 0; i < n; i++) { a2[i] = mint(a[i]); @@ -280,7 +291,7 @@ std::vector convolution_ll(const std::vector& a, static_assert(MOD1 % (1ull << MAX_AB_BIT) == 1, "MOD1 isn't enough to support an array length of 2^24."); static_assert(MOD2 % (1ull << MAX_AB_BIT) == 1, "MOD2 isn't enough to support an array length of 2^24."); static_assert(MOD3 % (1ull << MAX_AB_BIT) == 1, "MOD3 isn't enough to support an array length of 2^24."); - assert(a.size() + b.size() - 1 <= (1ull << MAX_AB_BIT)); + assert(n + m - 1 <= (1 << MAX_AB_BIT)); auto c1 = convolution(a, b); auto c2 = convolution(a, b); From 1a2785d62178978bef3af9529f6774b534135835 Mon Sep 17 00:00:00 2001 From: Kohei Morita Date: Sun, 26 Mar 2023 15:51:39 +0900 Subject: [PATCH 2/2] fix assertion --- atcoder/convolution.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/atcoder/convolution.hpp b/atcoder/convolution.hpp index 059b5c6..ecfbc44 100644 --- a/atcoder/convolution.hpp +++ b/atcoder/convolution.hpp @@ -221,12 +221,11 @@ std::vector convolution(std::vector&& a, std::vector&& b) { if (!n || !m) return {}; int z = (int)internal::bit_ceil((unsigned int)(n + m - 1)); - assert(mint::mod() % z == 1); + assert((mint::mod() - 1) % z == 0); if (std::min(n, m) <= 60) return convolution_naive(a, b); return internal::convolution_fft(a, b); } - template * = nullptr> std::vector convolution(const std::vector& a, const std::vector& b) { @@ -234,7 +233,7 @@ std::vector convolution(const std::vector& a, if (!n || !m) return {}; int z = (int)internal::bit_ceil((unsigned int)(n + m - 1)); - assert(mint::mod() % z == 1); + assert((mint::mod() - 1) % z == 0); if (std::min(n, m) <= 60) return convolution_naive(a, b); return internal::convolution_fft(a, b); @@ -250,7 +249,7 @@ std::vector convolution(const std::vector& a, const std::vector& b) { using mint = static_modint; int z = (int)internal::bit_ceil((unsigned int)(n + m - 1)); - assert(mint::mod() % z == 1); + assert((mint::mod() - 1) % z == 0); std::vector a2(n), b2(m); for (int i = 0; i < n; i++) {