We can enumerate all the arrays that sum to $M$ in $O(M2^M)$ time and check if any of them satisfy the conditions in the problem statement.
My C++ code:
#include <iostream> #include <vector> using namespace std; int flag; vector<int> ans; int popcount(int x){ if(x == 1 || x == 2 || x == 4) return 1; if(x == 7) return 3; return 2; } void dfs(int m, int k){ if(m == 0 && k == 0){ flag = 1; return ; } if(!flag){ for(int i = 1; i<=m; i++){ ans.push_back(i); dfs(m - i, k^popcount(i)); if(flag) break ; ans.pop_back(); } } } int main(){ int T; cin >> T; for(int i = 0; i<T; i++){ int m, k; cin >> m >> k; flag = 0; ans.clear(); dfs(m, k); if(flag){ cout << ans.size() << "\n"; for(int x : ans){ cout << x << " "; } cout << "\n"; }else{ cout << "-1\n"; } } }
As $M$ is large relative to $K$, we will employ a strategy as follows:
My C++ code:
#include <iostream> #include <vector> using namespace std; int main(){ int T; cin >> T; while(T--){ int m, k; cin >> m >> k; int x = (1 << k) - 1; int d = m - x; vector<int> ans; if(d%2 == 0){ ans = {x, d/2, d/2}; }else{ ans = {x, 1, 2, (d - 3)/2, (d - 3)/2}; } //for this subtask, a solution always exists! cout << ans.size() << "\n"; for(int i = 0; i<ans.size(); i++){ cout << ans[i] << " "; } cout << "\n"; } }
We now have to improve our solution for when $M$ is smaller relative to $K$. We will still use the same strategy as before of finding two arrays $a$ and $b$ where $a$ has popcount xor equal to $K$ and $b$ has popcount xor equal to $0$. From a greedy standpoint, we should aim to minimize the sum of elements in $a$ to give more leeway for constructing $b$.
For each bit $i$ on in $K$, we will add $2^{2^i} - 1$ to $a$. Notably $2^{2^i} - 1$ is the smallest integer with popcount $2^i$. For instance if $K = 5$, we would take $a = [1, 15]$ or if $K = 12$ we would take $a = [15, 255]$.
$a$ has the minimal sum of any array with popcount xor equal to $K$. We will prove this with a contradiction.
Suppose $a$ was not of the form above. Consider any element $x$ in $a$ not of the form $2^{2^i}-1$, and suppose it has popcount $c$.
Our new array has the same popcount xor, but a smaller sum, thus our original $a$ could not have the minimal sum.
For instance, if our $a$ with popcount xor equal to $7$ was $[1, 63]$. We could replace $63$ (with popcount $6$) with $[2^{2^1} - 1, 2^{2^2}-1] = [3, 15]$ to get a new $a$ with a smaller sum and popcount xor equal to $7$.
Let $d = M - \sum a_i$. If $d < 0$, no such array exists, as we cannot make an array $a$ with smaller sum and popcount xor equal to $K$.
If $d \geq 2$, we can use our idea from the previous subtask.
If $d = 0$, we can have $b$ be empty.
Finally, we just have to solve when $d = 1$. In other words, we need to increase the sum of $a$ by $1$ without changing the xor of its popcounts. This is only possible when $a$ contains $1$, and we would replace that occurrence of $1$ with a $2$. There is no other way to change the array $a$ into any other array with sum $M$ and popcount xor equal to $K$ as $a$, as defined above, has minimal sum.
Our final complexity is $O(\log K)$ per test case.
My C++ code:
#include <iostream> #include <vector> using namespace std; int main(){ cin.tie(0) -> sync_with_stdio(0); int T; cin >> T; while(T--){ int m, k; cin >> m >> k; vector<int> a; int x = 0; for(int i = 0; i<5; i++){ if(k&(1 << i)){ a.push_back((1 << (1 << i)) - 1); x += a.back(); } } int d = m - x; vector<int> b; int flag = 0; if(d < 0){ flag = 1; }else if(d >= 2){ if(d%2 == 0){ b = {d/2, d/2}; }else{ b = {1, 2, (d-3)/2, (d-3)/2}; } }else if(d == 0){ b = {}; }else{ if(a[0] == 1){ a[0] = 2; }else{ flag = -1; } } if(flag){ cout << "-1\n"; }else{ cout << a.size() + b.size() << "\n"; for(int i : a) cout << i << " "; for(int i : b) cout << i << " " ; cout << "\n"; } } }