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.
The operation only cares about parity, not about the actual values. So first ask: do you have both an odd and an even number?
If all numbers have the same parity, then no pair has different parity, so the wand is basically a decorated stick. No swap is possible.
If there is at least one odd and one even, any odd-even pair can be swapped directly.
What about swapping two numbers with the same parity? Use one number of the opposite parity as a temporary buffer and do it in 3 swaps.
So the reachable set is simple: if both parities exist, you can permute the array however you want, so output the sorted array. Otherwise, output the original array.
Key observation
The wand can swap two values exactly when their parities differ. That sounds restrictive, but it is only restrictive in one case: when the whole array has the same parity.
If all values are odd, every pair is odd-odd, so no swap is legal. If all values are even, every pair is even-even, same deal. The answer is just the original array.
Now suppose the array has at least one odd and at least one even.
Then any odd-even pair can be swapped directly. The only suspicious part is whether we can swap two odds, or two evens. Turns out yes, because the opposite parity value can act as a buffer.
Say we want to swap two odd values and , and somewhere else there is an even value :
After these three legal swaps, and have exchanged positions, and is back where it started. Same logic works for swapping two evens using an odd buffer.
So when both parities exist, we can perform any transposition of two elements. And since arbitrary transpositions generate every permutation, we can rearrange the array however we want.
The lexicographically smallest permutation of a multiset is just the sorted array. No galaxy-brain DP, no cursed graph theory hiding under the bed. Sort it and move on.
Algorithm
For each test case:
Correctness proof
We prove that the algorithm outputs the lexicographically smallest reachable array.
If the array contains only one parity, then for every pair of positions , . Therefore no swap is legal. The only reachable array is the original array, so the algorithm is correct in this case.
Now suppose the array contains both parities. Any two elements of different parity can be swapped directly by the operation.
For two elements of the same parity, choose any element of the opposite parity as a buffer. Using the three-swap sequence described above, those two same-parity elements can be swapped while the buffer returns to its original position. Every swap in the sequence is legal because it is always between opposite parities.
Therefore, when both parities exist, any pair of elements can be swapped. Since any permutation can be built from pairwise swaps, every permutation of the array is reachable.
Among all permutations of the array, the lexicographically smallest one is the nondecreasing sorted order. The algorithm outputs exactly that order, so it is correct.
Complexity
Checking parity takes . Sorting takes if needed. Across all test cases, the total is at most , so this easily fits.
#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;
cin >> n;
vector<ll> a(n);
bool hasOdd = false, hasEven = false;
for (ll &x : a) {
cin >> x;
if (x % 2) hasOdd = true;
else hasEven = true;
}
if (hasOdd && hasEven) {
sort(a.begin(), a.end());
}
for (ll x : a) {
cout << x << ' ';
}
cout << '\n';
}
return 0;
}#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;
cin >> n;
vector<ll> a(n);
bool hasOdd = false, hasEven = false;
for (ll &x : a) {
cin >> x;
if (x % 2) hasOdd = true;
else hasEven = true;
}
if (hasOdd && hasEven) {
sort(a.begin(), a.end());
}
for (ll x : a) {
cout << x << ' ';
}
cout << '\n';
}
return 0;
}