Language: C++

#define _CRT_SECURE_NO_WARNINGS
#define NDEBUG
#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <memory>
#include <utility>
#include <vector>

template <typename Integral,
	std::size_t bitsize = std::numeric_limits<Integral>::digits()>
	class WaveletMatrix {
	public:
		using value_type = Integral;
		using size_type = std::size_t;

	private:
		using uint32 = std::uint_least32_t;
		static size_type popcount32(uint32 c) {
#ifdef __GNUC__
			return __builtin_popcount(c);
#elif _MSC_VER_
			return _mm_popcnt_u32(c);
#else
			c = (c & 0x55555555) + ((c >> 1) & 0x55555555);
			c = (c & 0x33333333) + ((c >> 2) & 0x33333333);
			c = (c + (c >> 4)) & 0x0F0F0F0F;
			c += c >> 8;
			c += c >> 16;
			return static_cast<size_type>(c) & 0x3F;
#endif
		}
		struct FID {
			std::vector<uint32> dic;
			size_type cnt;
			value_type bit;
			FID() {}
			FID(const size_type bsize) : dic(bsize, 0) {}
			void set(const size_type index) {
				dic[index >> 4 | 1] |= static_cast<uint32>(1) << (index & 0x1f);
			}
			void build() {
				const size_type len = dic.size();
				for (size_type j = 2; j < len; j += 2)
					dic[j] = dic[j - 2] + popcount32(dic[j - 1]);
			}
			size_type rank(const size_type last) const {
				return static_cast<size_type>(
					dic[last >> 4 & ~static_cast<size_type>(1)]) +
					popcount32(dic[last >> 4 | 1] &
					(static_cast<size_type>(1) << (last & 0x1f)) - 1);
			}
			bool access(const size_type index) const {
				return dic[index >> 4 | 1] >> (index & 0x1f) & 1;
			}
		};
		std::array<FID, bitsize> matrix;
		value_type NOT_FOUND;
		size_type size_;

	public:
		WaveletMatrix(std::vector<value_type> data, const value_type NOT_FOUND = 0)
			: size_(data.size()), NOT_FOUND(NOT_FOUND) {
			const size_type len = data.size(), block = ((len >> 5) + 1) << 1;
			std::vector<value_type> L(len), R(len);
			size_type l, r;
			value_type temp = static_cast<value_type>(1) << (bitsize - 1);
			for (auto &x : matrix) {
				new (std::addressof(x)) FID(block);
				x.bit = temp;
				temp = temp >> 1 & ~temp;
				l = 0;
				r = 0;
				for (size_type j = 0; j < len; ++j)
					if (data[j] & x.bit)
						R[r++] = data[j], x.set(j);
					else
						L[l++] = data[j];
				x.cnt = l;
				x.build();
				std::swap(data, L);
				std::copy(R.begin(), R.begin() + r, data.begin() + l);
			}
		}
		value_type access(size_type index) const {
			assert(index < size());
			value_type ret = 0;
			for (const auto &x : matrix)
				if (x.access(index))
					ret |= x.bit, index = x.rank(index) + x.cnt;
				else
					index -= x.rank(index);
			return ret;
		}
		value_type operator[](const size_type index) const {
			assert(index < size());
			return access(index);
		}
		size_type rank(size_type first, size_type last, const value_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			for (const auto &x : matrix)
				if (data & x.bit)
					first = x.rank(first) + x.cnt, last = x.rank(last) + x.cnt;
				else
					first -= x.rank(first), last -= x.rank(last);
			return last - first;
		}
		value_type quantile(size_type first, size_type last, size_type k) const {
			assert(first < size());
			assert(last <= size());
			assert(first < last);
			assert(last - first > k);
			value_type ret = 0;
			for (const auto &x : matrix) {
				const size_type l = x.rank(first), r = x.rank(last);
				if (r - l > k)
					first = l + x.cnt, last = r + x.cnt, ret |= x.bit;
				else
					first -= l, last -= r, k -= r - l;
			}
			return ret;
		}
		value_type rquantile(size_type first, size_type last, size_type k) const {
			assert(first < size());
			assert(last <= size());
			assert(first < last);
			assert(last - first > k);
			return quantile(first, last, last - first - k - 1);
		}
		size_type less_than(size_type first, size_type last,
			const value_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			size_type ret = 0;
			for (const auto &x : matrix) {
				if (data & x.bit) {
					ret += last - first + x.rank(first) - x.rank(last);
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return ret + last - first;
		}
		size_type more_than(size_type first, size_type last,
			const value_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			size_type ret = 0;
			for (const auto &x : matrix) {
				if (data & x.bit) {
					first = x.rank(first) + x.cnt;
					last = x.rank(last) + x.cnt;
				}
				else {
					ret += x.rank(last) - x.rank(first);
					first -= x.rank(first);
					last -= x.rank(last);
				}
			}
			return ret;
		}
		size_type rangefreq(size_type first, size_type last, const value_type lower,
			const value_type upper) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			assert(lower <= upper);
			return less_than(first, last, upper) - less_than(first, last, lower);
		}
		value_type successor(const size_type first, const size_type last,
			const value_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			const size_type k = less_than(first, last, data);
			return last - first == k ? NOT_FOUND : rquantile(first, last, k);
		}
		value_type predecessor(const size_type first, const size_type last,
			const value_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			const size_type k = more_than(first, last, data);
			return last - first == k ? NOT_FOUND : quantile(first, last, k);
		}
		value_type strict_succ(const size_type first, const size_type last,
			const value_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			const size_type k = more_than(first, last, data);
			return k ? quantile(first, last, k - 1) : NOT_FOUND;
		}
		value_type strict_pred(const size_type first, const size_type last,
			const value_type data) const {
			assert(first <= size());
			assert(last <= size());
			assert(first <= last);
			const size_type k = less_than(first, last, data);
			return k ? rquantile(first, last, k - 1) : NOT_FOUND;
		}
		size_type size() const noexcept { return size_; }
		bool empty() const noexcept { return size() == 0; }
};


#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <string>
#include <type_traits>

template <typename Integral = std::size_t> class irange {
public:
	using value_type = Integral;
	using const_value = const value_type;
	class irangeitr {
		friend irange;
		value_type i;
		irangeitr(const_value x) noexcept : i(x) {}
	public:
		void operator++() noexcept { ++i; }
		const_value operator*() const noexcept { return i; }
		bool operator!=(const irangeitr &x) const noexcept { return i != x.i; }
	};
	class reverse {
		friend irange;
		const_value f, l;
		reverse(const_value x, const_value y) noexcept : f(x), l(y) {}
	public:
		class revitr {
			friend reverse;
			value_type i;
			revitr(const_value x) noexcept : i(x) {}
		public:
			void operator++() noexcept { --i; }
			const_value operator*() const noexcept { return i - 1; }
			bool operator!=(const revitr &x) const noexcept { return i != x.i; }
		};
		revitr begin() const noexcept { return revitr(f); }
		revitr end() const noexcept { return revitr(l); }
	};
private:
	const_value f, l;
public:
	irange(const_value first, const_value last) noexcept : f(first), l(last) {}
	irangeitr begin() const noexcept { return irangeitr(f); }
	irangeitr end() const noexcept { return irangeitr(l); }
	reverse rev() const noexcept { return reverse(l, f); }
};

template<class T> bool maxi(T&a, const T&b) { if (b < a) return 0; a = b; return 1; }
template<class T> bool mini(T&a, const T&b) { if (a < b) return 0; a = b; return 1; }
template<class T> bool smaxi(T&a, const T&b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> bool smini(T&a, const T&b) { if (b < a) { a = b; return 1; } return 0; }
template<typename T>auto scan(T&d)->typename std::enable_if<std::is_signed<T>::value>::type {
	d = 0; int c, f = 0;
	while (c = fgetc(stdin), c == ' ' || c == '\n');
	if (c == '-') f = 1, c = fgetc(stdin);
	do d = d * 10 + c - '0';while (c = fgetc(stdin), c != ' '&&c != '\n');
	if (f) d = -d;
}
template<typename T>auto scan(T&d)->typename std::enable_if<!std::is_signed<T>::value>::type {
	d = 0; int c;
	while (c = fgetc(stdin), c == ' ' || c == '\n');
	do d = d * 10 + c - '0';while (c = fgetc(stdin), c != ' '&&c != '\n');
}
void scan(char&d) { while (d = fgetc(stdin), d == ' ' || d == '\n'); }
void scan(double&d) { scanf("%lf", &d); }
void scan(std::string&d) {
	d.clear(); int c;
	while (c = fgetc(stdin), c == ' ' || c == '\n');
	do d.push_back(c); while (c = fgetc(stdin), c != ' '&&c != '\n');
}
template<typename F, typename...R>void scan(F&f, R&...r) { scan(f); scan(r...); }
template<typename T>T input() { T d; scan(d); return d; }
template <typename T>auto print(T d)->typename std::enable_if<std::is_signed<T>::value>::type {
	static int c[20];int i = 0;bool f = 0;
	if (d<0) { f = 1;d = -d; }
	while (d) { c[i++] = d % 10;d /= 10; }
	if (!i)c[i++] = 0;
	if (f)fputc('-', stdout);
	while (i--)fputc(c[i] + '0', stdout);
}
template<typename T>auto print(T d)->typename std::enable_if<!std::is_signed<T>::value>::type {
	static int c[20];int i = 0;
	while (d) { c[i++] = d % 10;d /= 10; }
	if (!i)c[i++] = 0;
	while (i--)fputc(c[i] + '0', stdout);
}
template<>void print<char>(char d) { fputc(d, stdout); }
template<>void print<double>(double d) { printf("%f", d); }
void print(const std::string &d) { for (const auto c : d)fputc(c, stdout); }
void print(const char *c) { while (*c != '\0')fputc(*(c++), stdout); }
void print() {}
template<typename F, typename...R>void print(F f, R...r) { print(f);print(r...); }
template<typename...R>void println(R...r) { print(r...);fputc('\n', stdout); }
template<typename...R>int END(R...r) { println(r...);return 0; }

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
using intl32 = std::int_least32_t;
using intl64 = std::int_least64_t;
using uintl32 = std::uint_least32_t;
using uintl64 = std::uint_least64_t;
int main() {
	const auto n = input<uintl32>();
	std::vector<uintl32> a(n), b(n), c(n);
	for (auto& e : a)
		scan(e);
	for (auto& e : b)
		scan(e);
	uintl32 ans = 0;
	if (n & 1) {
		for (const auto e : a)
			ans ^= e;
		for (const auto e : b)
			ans ^= e;
	}
	for (const auto i:irange<uintl32>(1,29)) {
		const auto pbit = static_cast<uint32>(1) << i;
		for (uint32 j = 0;j < n;++j)
			c[j] = b[j] & (pbit - 1);
		WaveletMatrix<uint32, 28> W(c);
		for (const auto e : a)
			if (W.more_than(0, n, ~e&(pbit - 1)) & 1)
				ans ^= pbit;
	}
	println(ans);
	return 0;
}


Compiler output:
a.cc: In function 'int main()':
a.cc:337:46: error: no matching function for call to 'WaveletMatrix<long unsigned int, 28>::WaveletMatrix(std::vector<unsigned int>&)'
  337 |                 WaveletMatrix<uint32, 28> W(c);
      |                                              ^
a.cc:65:17: note: candidate: 'WaveletMatrix<Integral, bitsize>::WaveletMatrix(std::vector<Integral>, value_type) [with Integral = long unsigned int; long unsigned int bitsize = 28; value_type = long unsigned int]'
   65 |                 WaveletMatrix(std::vector<value_type> data, const value_type NOT_FOUND = 0)
      |                 ^~~~~~~~~~~~~
a.cc:65:55: note:   no known conversion for argument 1 from 'vector<unsigned int,allocator<unsigned int>>' to 'vector<long unsigned int,allocator<long unsigned int>>'
   65 |                 WaveletMatrix(std::vector<value_type> data, const value_type NOT_FOUND = 0)
      |                               ~~~~~~~~~~~~~~~~~~~~~~~~^~~~
a.cc:15:15: note: candidate: 'WaveletMatrix<long unsigned int, 28>::WaveletMatrix(const WaveletMatrix<long unsigned int, 28>&)'
   15 |         class WaveletMatrix {
      |               ^~~~~~~~~~~~~
a.cc:15:15: note:   no known conversion for argument 1 from 'std::vector<unsigned int>' to 'const WaveletMatrix<long unsigned int, 28>&'
a.cc:15:15: note: candidate: 'WaveletMatrix<long unsigned int, 28>::WaveletMatrix(WaveletMatrix<long unsigned int, 28>&&)'
a.cc:15:15: note:   no known conversion for argument 1 from 'std::vector<unsigned int>' to 'WaveletMatrix<long unsigned int, 28>&&'