C. Beautiful XOR
Problem Statement
You are given two integers and . You are allowed to perform the following operation any number of times (including zero):
- choose any integer such that (the current value of , not initial),
- set . Here, represents the bitwise XOR operator.
After performing a sequence of operations, you want the value of to become exactly .
Find a sequence of at most 100 operations (values of used in each operation) that transforms into , or report that it is impossible.
Note that you are not required to find the minimum number of operations, but any valid sequence of at most 100 operations.
Solution
Let the initial value be and the target value be . After a series of operations with chosen integers , the final value of will be . Let . We want the final value to be , so we have the equation: This implies that the total XOR sum of the operations must be .
Our task is to find a sequence of values that are valid (i.e., at each step) and whose XOR sum is .
A simple way to construct the total XOR sum is to break it down into its constituent powers of 2. Any integer can be uniquely represented as a sum of distinct powers of 2, which correspond to the set bits in its binary representation. If we perform an XOR operation for each of these powers of 2, their total XOR sum will be equal to .
Let’s say , where each is a distinct power of 2. We can use this sequence of as our operations . The condition for each operation is that .
Let’s analyze this condition. Let be the largest power of 2 in the binary representation of . This corresponds to the most significant bit where and differ.
Case 1: (the initial value) If the largest required power of 2, , is less than or equal to the initial value of , a solution is possible. Let the required operations be where . At any step, when we perform an operation , we need to ensure . Since is the most significant bit of difference, all bits of at positions higher than are the same as in . The condition implies that the most significant bit of is at least at the same position as . When we apply operations with , these operations only affect bits lower than the most significant bit of . Therefore, the value of remains greater than or equal to . This ensures that for any subsequent operation . Thus, all operations in the sequence are valid.
Case 2: (the initial value) If the largest power of 2 required for the transformation, , is greater than the initial , it is impossible to reach . Let . The condition means that . This implies that all bits of at or above position are 0. For any operation, we must choose an . If , then we must also have . The result of the XOR operation, , will also be less than . This is because the XOR of two numbers cannot produce a result with a more significant bit than the larger of the two numbers. Since we start with , we can never reach a value greater than or equal to . However, since is part of , the -th bit of and must differ. As the -th bit of is 0, the -th bit of must be 1. This means . Since we can never reach a value , it is impossible to transform into .
So, the strategy is:
- Calculate .
- If , no operations are needed.
- Find the largest power of 2 in , let it be .
- If , the solution is the sequence of all powers of 2 that constitute .
- If , no solution exists.
View Code
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <tuple>
#include <vector>
using namespace std;
#define int long long
// #define mod 1000000007
#define N 500005
void solve() {
int a, b;
cin >> a >> b;
int x = a ^ b;
vector<int> ans;
int pow = 1;
if (x == 0){
cout << 0 << endl;
return;
}
while(x > 0) {
if(x & 1) {
ans.push_back(pow);
}
pow *= 2;
x >>= 1;
}
if (ans.back() <= a ) {
cout << ans.size() <<endl;
for (int i = 0; i < ans.size(); i++) {
cout << ans[i] << " ";
}
cout << endl;
} else {
cout << -1 << endl;
}
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#ifdef DEBUG
freopen("./input.txt", "r", stdin);
#endif
int t;
cin >> t;
while (t--) {
#ifdef DEBUG
static int test_num = 1;
cout << "test case: " << test_num++ << endl;
#endif
solve();
}
}