From 7e06c5f89158c3a5eb5185c84b01f651ab0f777f Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 6 Mar 2026 12:02:07 -0700 Subject: [PATCH 1/3] first draft of xor conv --- library/convolution/xor_convolution.hpp | 21 +++++++++++++++++++ .../convolution/xor_convolution.test.cpp | 19 +++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 library/convolution/xor_convolution.hpp create mode 100644 tests/library_checker_aizu_tests/convolution/xor_convolution.test.cpp diff --git a/library/convolution/xor_convolution.hpp b/library/convolution/xor_convolution.hpp new file mode 100644 index 000000000..c81bbb62b --- /dev/null +++ b/library/convolution/xor_convolution.hpp @@ -0,0 +1,21 @@ +#pragma once +#include "../math/mod_division.hpp" +void fwht(int n, vi& a) { + for (int i = 1; i != n; i <<= 1) + for (int j = 0; j != n; j += i << 1) + for (int k = 0; k != i; k++) { + 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; +} From 5dd22f5aaa0c43f67df0e8ae186a390c32aa6269 Mon Sep 17 00:00:00 2001 From: GitHub Date: Fri, 6 Mar 2026 19:03:41 +0000 Subject: [PATCH 2/3] [auto-verifier] verify commit 7e06c5f89158c3a5eb5185c84b01f651ab0f777f --- .verify-helper/timestamps.remote.json | 1 + 1 file changed, 1 insertion(+) 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", From 05e100d83b3db7779f4573cce29167ffe17aa977 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Fri, 6 Mar 2026 12:07:47 -0700 Subject: [PATCH 3/3] add docs now --- library/convolution/xor_convolution.hpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/library/convolution/xor_convolution.hpp b/library/convolution/xor_convolution.hpp index c81bbb62b..f02bd767a 100644 --- a/library/convolution/xor_convolution.hpp +++ b/library/convolution/xor_convolution.hpp @@ -1,9 +1,16 @@ #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 <<= 1) - for (int j = 0; j != n; j += i << 1) - for (int k = 0; k != i; k++) { + 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;