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>

#ifdef __has_builtin
::std::size_t popcount64(::std::uint_fast64_t c) { return __builtin_popcountll(c); }
#else
::std::size_t popcount64(::std::uint_fast64_t c) {
	c = (c & 0x5555555555555555) + ((c & 0xAAAAAAAAAAAAAAAA) >> 1);
	c = (c & 0x3333333333333333) + ((c & 0xCCCCCCCCCCCCCCCC) >> 2);
	c = (c + (c >> 4)) & 0x0F0F0F0F0F0F0F0F;
	return static_cast<::std::size_t>(c * 0x0101010101010101 >> 56 & 0x7f);
}
#endif

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 uint64 = std::uint_fast64_t;
		struct FID {
			std::vector<uint64> dic;
			size_type cnt;
			value_type bit;
			FID() {}
			FID(const size_type bsize) : dic(bsize, 0) {}
			void set(const size_type index) {
				dic[index >> 5 | 1] |= static_cast<uint64>(1) << (index & 0x3f);
			}
			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 >> 5 & ~static_cast<size_type>(1)]) +
					popcount32(dic[last >> 5 | 1] &
					(static_cast<size_type>(1) << (last & 0x3f)) - 1);
			}
			bool access(const size_type index) const {
				return dic[index >> 5 | 1] >> (index & 0x3f) & 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<cstdio>
#include<vector>

int main() {
	using uint32 = unsigned int;
	uint32 n;
	scanf("%u", &n);
	std::vector<uint32> a(n), b(n), c(n);
	for (auto& e : a)
		scanf("%u", &e);
	for (auto& e : b)
		scanf("%u", &e);
	uint32 ans = 0;
	if (n & 1) {
		for (const auto e : a)
			ans ^= e;
		for (const auto e : b)
			ans ^= e;
	}
	for (uint32 i = 1;i <= 28;++i) {
		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;
	}
	printf("%u\n", ans);
	return 0;
}


Compiler output:
a.cc: In member function 'void WaveletMatrix<Integral, bitsize>::FID::build()':
a.cc:45:63: error: there are no arguments to 'popcount32' that depend on a template parameter, so a declaration of 'popcount32' must be available [-fpermissive]
   45 |                                         dic[j] = dic[j - 2] + popcount32(dic[j - 1]);
      |                                                               ^~~~~~~~~~
a.cc:45:63: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
a.cc: In member function 'WaveletMatrix<Integral, bitsize>::size_type WaveletMatrix<Integral, bitsize>::FID::rank(WaveletMatrix<Integral, bitsize>::size_type) const':
a.cc:50:41: error: there are no arguments to 'popcount32' that depend on a template parameter, so a declaration of 'popcount32' must be available [-fpermissive]
   50 |                                         popcount32(dic[last >> 5 | 1] &
      |                                         ^~~~~~~~~~
a.cc: In instantiation of 'void WaveletMatrix<Integral, bitsize>::FID::build() [with Integral = unsigned int; long unsigned int bitsize = 28]':
a.cc:80:12:   required from 'WaveletMatrix<Integral, bitsize>::WaveletMatrix(std::vector<Integral>, value_type) [with Integral = unsigned int; long unsigned int bitsize = 28; value_type = unsigned int]'
   80 |                                 x.build();
      |                                 ~~~~~~~^~
a.cc:237:32:   required from here
  237 |                 WaveletMatrix<uint32, 28> W(c);
      |                                              ^
a.cc:45:73: error: 'popcount32' was not declared in this scope; did you mean 'popcount64'?
   45 |                                         dic[j] = dic[j - 2] + popcount32(dic[j - 1]);
      |                                                               ~~~~~~~~~~^~~~~~~~~~~~
      |                                                               popcount64
a.cc: In instantiation of 'WaveletMatrix<Integral, bitsize>::size_type WaveletMatrix<Integral, bitsize>::FID::rank(WaveletMatrix<Integral, bitsize>::size_type) const [with Integral = unsigned int; long unsigned int bitsize = 28; WaveletMatrix<Integral, bitsize>::size_type = long unsigned int]':
a.cc:159:20:   required from 'WaveletMatrix<Integral, bitsize>::size_type WaveletMatrix<Integral, bitsize>::more_than(size_type, size_type, value_type) const [with Integral = unsigned int; long unsigned int bitsize = 28; size_type = long unsigned int; value_type = unsigned int]'
  159 |                                         first = x.rank(first) + x.cnt;
      |                                                 ~~~~~~^~~~~~~
a.cc:239:19:   required from here
  239 |                         if (W.more_than(0, n, ~e&(pbit - 1)) & 1)
      |                             ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
a.cc:50:51: error: 'popcount32' was not declared in this scope; did you mean 'popcount64'?
   50 |                                         popcount32(dic[last >> 5 | 1] &
      |                                         ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
   51 |                                         (static_cast<size_type>(1) << (last & 0x3f)) - 1);
      |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~