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!