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
i
th bits ofXOR
andAND
are both set, then we have a contradiction and noa
,b
fits the problem. - ... the
i
th bit ofXOR
andAND
are 0 and 1 respectively, then botha
andb
have thei
th bit set. - ... the
i
th bit ofXOR
andAND
are 1 and 0 respectively, then only onea
andb
have thei
th bit set. - ... if neither
XOR
norAND
have thei
th bit set, then nor doa
orb
.
_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!