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";
}
}
}