Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
For every , the values missing from inside are exactly the nonempty suffix . Therefore while .
Reverse the permutation: let and . Then the required XOR is So, for , you only need the relevant prefix minima of to XOR to . Once appears in , every later prefix minimum is harmlessly .
Let be the smallest power of two with . Every prefix minimum lies in , hence is smaller than ; XOR cannot magically create a bit at or above . Thus is impossible. This also handles : then , so only , equivalently , works.
The easy feasible cases need almost no construction. If , begin with . If , begin it with . Append every unused value afterward in any order. The relevant prefix minima are respectively all zero, or followed by zeroes.
The only remaining case is . Set and begin with . The numbers and share their highest bit, so ; the three values are distinct. The prefix minima are , whose XOR is . Append unused values, then output as the reverse of .
The evolving MEX looks annoying, but for a permutation it is really just a suffix minimum wearing a fake mustache.
Fix an index . The prefix and the remaining suffix partition all values . Therefore, the values from this range that are absent from the prefix are exactly The suffix is nonempty, so its minimum is at most and appears before any missing value . Hence
For the complete permutation, every value from through is present, so
Now reverse the permutation. Define and let be the prefix minima of .
Every nonempty suffix of is a prefix of . As ranges from to , the suffix minima above become exactly , only in the opposite order. XOR does not care about order, so the total is
Notice that is intentionally absent: the full prefix of would correspond to an empty prefix of , which the problem never asks about.
Set Our entire task is now to construct a permutation such that We will then output as the reverse of .
Let be the smallest power of two satisfying . Equivalently, is the smallest power of two strictly greater than .
Every is one of the values , so . Because is a power of two, every bit at position or higher is zero in every . Their XOR also has all those bits zero. Therefore, is necessary.
If , the answer is NO. XOR is weird, but it cannot invent a bit that none of its operands has.
It remains to show that every is achievable.
We only need to control a tiny prefix of . After placing , all later prefix minima equal , so the remaining unused values can be dumped afterward in any order.
Start with All relevant prefix minima are , so their XOR is .
Here itself is a legal permutation value. Start with The relevant prefix minima are followed by zeroes, if any. Their XOR is exactly .
The desired value is too large to place directly in the permutation. We split it into two legal prefix minima. Define and start with
We need to verify that is a valid new value. This case can occur only when . Let . Since is the smallest power of two at least , we have Thus both and have highest set bit . XOR removes that common bit, giving Also , because . Therefore so , , and are distinct legal values.
The relevant prefix minima begin with because . Their XOR is If the array is so short that the prefix containing is the excluded full prefix of , that changes nothing: the two required nonzero minima are still included, and omitted zeroes contribute nothing anyway.
In every case, append all still-unused values from through after this special prefix. The result is a permutation, and those appended values cannot alter any prefix minimum after has appeared.
Finally, reverse to obtain .
Suppose the algorithm outputs NO. Then . For every permutation, each relevant prefix minimum of its reverse is below , so their XOR is also below . It cannot equal $x`; therefore no valid permutation exists.
Now suppose the algorithm outputs a permutation. Its special values are distinct in each of the three cases, and every other value is appended exactly once, so and its reverse are permutations.
The construction makes the XOR of equal to : it is in the first case, followed by zeroes in the second case, and followed by zeroes in the third case. Using the suffix-minimum identity,
Thus every printed permutation satisfies the requirement.
For , . The feasibility test accepts only , meaning , and outputs . So the annoying edge case falls out automatically instead of demanding special-case spaghetti.
Constructing and printing the permutation takes time and memory per test case. The total time is , which fits the given bound.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
int x = k ^ n;
int bound = 1;
while (bound < n) bound <<= 1;
if (x >= bound) {
cout << "NO\n";
continue;
}
vector<int> a;
vector<char> used(n, false);
if (x > 0 && x < n) {
a.push_back(x);
used[x] = true;
} else if (x > 0) {
int y = (n - 1) ^ x;
a.push_back(n - 1);
a.push_back(y);
used[n - 1] = used[y] = true;
}
a.push_back(0);
used[0] = true;
for (int v = 0; v < n; ++v) {
if (!used[v]) a.push_back(v);
}
cout << "YES\n";
for (int i = n - 1; i >= 0; --i) {
cout << a[i] << (i ? ' ' : '\n');
}
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
int x = k ^ n;
int bound = 1;
while (bound < n) bound <<= 1;
if (x >= bound) {
cout << "NO\n";
continue;
}
vector<int> a;
vector<char> used(n, false);
if (x > 0 && x < n) {
a.push_back(x);
used[x] = true;
} else if (x > 0) {
int y = (n - 1) ^ x;
a.push_back(n - 1);
a.push_back(y);
used[n - 1] = used[y] = true;
}
a.push_back(0);
used[0] = true;
for (int v = 0; v < n; ++v) {
if (!used[v]) a.push_back(v);
}
cout << "YES\n";
for (int i = n - 1; i >= 0; --i) {
cout << a[i] << (i ? ' ' : '\n');
}
}
}