diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 50350ad30..a62a5bf48 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -2,6 +2,7 @@ "tests/library_checker_aizu_tests/convolution/gcd_convolution.test.cpp": "2025-08-28 13:19:16 -0600", "tests/library_checker_aizu_tests/convolution/lcm_convolution.test.cpp": "2025-08-28 13:19:16 -0600", "tests/library_checker_aizu_tests/convolution/min_plus_convolution.test.cpp": "2024-11-17 14:04:03 -0600", +"tests/library_checker_aizu_tests/convolution/xor_convolution.test.cpp": "2026-03-06 12:02:07 -0700", "tests/library_checker_aizu_tests/data_structures/binary_search_example.test.cpp": "2024-11-18 10:51:39 -0600", "tests/library_checker_aizu_tests/data_structures/binary_trie.test.cpp": "2026-01-18 02:20:40 +0000", "tests/library_checker_aizu_tests/data_structures/bit.test.cpp": "2026-01-23 04:31:29 +0000", diff --git a/library/convolution/xor_convolution.hpp b/library/convolution/xor_convolution.hpp new file mode 100644 index 000000000..f02bd767a --- /dev/null +++ b/library/convolution/xor_convolution.hpp @@ -0,0 +1,28 @@ +#pragma once +#include "../math/mod_division.hpp" +//! https://codeforces.com/blog/entry/127823 +//! @code +//! vi c = xor_conv(a, b); +//! // must have sz(a) == sz(b) == a power of 2 +//! // c[k] = sum of a[i]*b[j] where i^j==k +//! @endcode +//! @time O(n log n) +//! @space O(n) +void fwht(int n, vi& a) { + for (int i = 1; i < n; i *= 2) + for (int j = 0; j < n; j += 2 * i) rep(k, 0, i) { + int x = a[j + k], y = a[i + j + k]; + a[j + k] = (x + y) % mod; + a[i + j + k] = (x - y + mod) % mod; + } +} +vi xor_conv(vi& a, vi& b) { + int n = sz(a), inv = mod_div(1, n); + fwht(n, a); + fwht(n, b); + vi res(n); + rep(i, 0, n) res[i] = 1LL * a[i] * b[i] % mod; + fwht(n, res); + rep(i, 0, n) res[i] = 1LL * res[i] * inv % mod; + return res; +} diff --git a/tests/library_checker_aizu_tests/convolution/xor_convolution.test.cpp b/tests/library_checker_aizu_tests/convolution/xor_convolution.test.cpp new file mode 100644 index 000000000..f3a45752b --- /dev/null +++ b/tests/library_checker_aizu_tests/convolution/xor_convolution.test.cpp @@ -0,0 +1,19 @@ +#define PROBLEM \ + "https://judge.yosupo.jp/problem/bitwise_xor_convolution" +#include "../template.hpp" +#include "../../../library/convolution/xor_convolution.hpp" +istream& operator>>(istream& is, vector& v) { + for (int i = 0; i < sz(v); i++) is >> v[i]; + return is; +} +int main() { + cin.tie(0)->sync_with_stdio(0); + int n; + cin >> n; + vi a(1 << n), b(1 << n); + cin >> a >> b; + vi c = xor_conv(a, b); + for (int i = 0; i < (1 << n); i++) cout << c[i] << ' '; + cout << '\n'; + return 0; +}