1790E: Vlad and a Pair of Numbers ⧉
The task is to find two integers a, b given an integer XOR where XOR = a ^ b and XOR = (a + b) / 2.
The solution is based around the fact that the XOR of two numbers is equal to their sum minus twice their bitwise AND.
*(Here's a nice explanation of the above).
Being as a ^ b = a + b - 2 * (a & b), if we know a ^ b and a + b, we can find a & b. And if we have a ^ b and a & b, we can generate candidates for a and b with simple deduction.
Essentially, we iterate over the bits of XOR = a ^ b and AND = a & b and set bits of our candidate a and b based on whatever combination of set bits we find.
Namely, if
- ... the ith bits ofXORandANDare both set, then we have a contradiction and noa,bfits the problem.
- ... the ith bit ofXORandANDare 0 and 1 respectively, then bothaandbhave theith bit set.
- ... the ith bit ofXORandANDare 1 and 0 respectively, then only oneaandbhave theith bit set.
- ... if neither XORnorANDhave theith bit set, then nor doaorb.
_54#include <iostream>_54_54using ll = long long;_54_54std::pair<int,int> find_a_b_from_sum_XOR(ll sum, ll XOR) {_54  // (a&b)*2 = a+b - (a^b)_54  ll AND = (sum - XOR) / 2;_54  int a = 0, b = 0;_54_54  // find a, b s.t. a^b = `XOR` and a&b = `AND`_54  for (int i = 0; i < 8 * sizeof(ll); i++) {_54    ll XOR_i = XOR & 1 << i;_54    ll AND_i = AND & 1 << i;_54_54    // ith bit of `XOR` and `AND` can't both be set._54    if (XOR_i != 0 && AND_i != 0) {_54      return {-1, -1};_54_54      // ... if the AND bit is set and the XOR bit is not set,_54      // both a and b have this bit set._54    } else if (AND_i != 0) {_54      a |= 1 << i;_54      b |= 1 << i;_54_54      // ... if the XOR bit is set, only one of the two has_54      // this bit set. Let's just say it's A._54    } else if (XOR_i != 0) {_54      a |= 1 << i;_54    }_54  }_54_54  return {a, b};_54}_54_54void solve() {_54  // find a, b st. a^b == (a+b)/2;_54  // find a, b st. a^b == XOR and 2 * XOR = a+b;_54  ll XOR;_54  std::cin >> XOR;_54  ll sum = 2 * XOR;_54  auto [a,b] = find_a_b_from_sum_XOR(sum, XOR);_54  if (a == -1 || a+b != sum) std::cout << -1 << '\n';_54  else std::cout << a << ' ' << b << '\n';_54}_54_54_54int main() {_54  int t;_54  std::cin >> t;_54  for (int tc = 1; tc <= t; ++tc) {_54    solve();_54  }_54  return 0;_54}
If you found this solution helpful, consider leaving a star!