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.
Lexicographic order is brutally simple: the first position where two arrays differ decides everything. So focus on making the earliest possible position as large as possible.
The maximum possible first element is . If , there is only one useful way to put at the front: reverse the segment from position to the current position of .
If , then changing position would only make the array worse. So the optimal reversal must stay completely inside the suffix starting at position .
More generally, scan from left to right. As long as , that position is already as good as it can ever be. Touching it would be self-sabotage.
Let be the first position where . The best move is forced: reverse from to the position of value . If no such exists, the permutation is already descending, so reverse any length- segment.
Lexicographic maximization cares about the earliest position first. Later positions are background noise until the first difference is settled.
The absolute lexicographically maximum permutation of length is
We cannot arbitrarily rearrange the array, but we can choose one segment and reverse it. So we scan from left to right and keep asking: is this position already as large as it possibly can be?
At position using -indexed notation, if all previous positions are already optimal, then the largest remaining value is
If , great. That position is perfect. Any reversal that changes it would put a smaller value there, making the whole permutation lexicographically worse. So we leave it alone and move on.
Now suppose is the first position where
All values larger than must already appear in positions , because those positions matched the descending maximum prefix. Therefore the best possible value for position is exactly .
Where can that value come from? Since is a permutation, it appears at one unique position . To move into position using one reversal, the segment must start at and end at :
After reversing this segment, becomes the new value at position . This gives the largest possible prefix, and lexicographic order says that is all that matters. No fancy suffix optimization can compensate for losing earlier. That's the whole trick; don't overthink it.
If the scan never finds such an , then the permutation is already
which is lexicographically maximum among all permutations. Since the operation must be performed exactly once, we can choose a segment of length , which changes nothing.
Algorithm:
Proof of correctness:
Consider the first index where the original permutation differs from the descending permutation. For every , we have , the maximum possible value at that position after fixing all previous positions. Any reversal touching one of these positions would replace it with a smaller value, so the result would be lexicographically worse than simply preserving this prefix.
Thus an optimal reversal must start at or after . If it starts after , then position remains , which is smaller than . But is still available somewhere after , so we can do better by moving it to position .
The only reversal that moves the value to position is reversing the segment from to its current position. Therefore this move gives the maximum possible value at the first position where improvement is possible. Since lexicographic order is decided by the earliest differing position, this result is optimal.
If no such index exists, the permutation is already the descending permutation, which is globally lexicographically maximum. A length- reversal preserves it, so it is valid and optimal.
Complexity:
For each test case, building positions, scanning, and reversing take time. The memory usage is . Across all test cases, the total time is , which fits easily.
#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<int> p(n), pos(n + 1);
for (int i = 0; i < n; i++) {
cin >> p[i];
pos[p[i]] = i;
}
for (int i = 0; i < n; i++) {
int want = n - i;
if (p[i] != want) {
reverse(p.begin() + i, p.begin() + pos[want] + 1);
break;
}
}
for (int x : p) cout << x << ' ';
cout << '\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;
cin >> n;
vector<int> p(n), pos(n + 1);
for (int i = 0; i < n; i++) {
cin >> p[i];
pos[p[i]] = i;
}
for (int i = 0; i < n; i++) {
int want = n - i;
if (p[i] != want) {
reverse(p.begin() + i, p.begin() + pos[want] + 1);
break;
}
}
for (int x : p) cout << x << ' ';
cout << '\n';
}
}