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.
A bad array is exactly an array whose comparison signs contain ++++ or ---- somewhere. You do not need to think about all subsequences, only adjacent comparisons in the produced .
Try to make the comparison signs of alternate in small groups. If every two picks create one rise and one fall, then a run of four equal signs is impossible. That is already overkill, but overkill is great when it is clean.
Suppose the current deque ends are and with . If you take first and then , those two picked values go upward. If you take first and then , those two picked values go downward.
So process the deque in pairs. For one pair, output the smaller end then the larger end; for the next pair, output the larger end then the smaller end; then repeat. The internal sign of each pair alternates: up, down, up, down...
The only thing left is checking the sign between two neighboring pairs. It can be anything, but it is surrounded by opposite internal signs. Around every pair boundary the pattern looks like either + ? - or - ? +, so four equal signs can never form. Done.
The annoying part of the statement is that it talks about five numbers. Translate it into signs and it becomes much less dramatic.
For each adjacent pair in the final array , write:
+ if - if Since is made from a permutation, equality never happens. A bad segment of length is exactly four equal signs in a row:
++++----So our real job is: choose from the deque so the sign string has no run of length .
Pair Trick
Look at the two current ends of the deque. Call them and .
If :
L then R creates an increasing pairR then L creates a decreasing pairIf , the opposite order does the same thing. In general:
And because both values are ends, after removing the first one, the other one is still an end. No magic, no hidden data structure, just deque physics.
Now do this in pairs:
So inside the pairs, the comparison signs alternate:
There is also one comparison sign between consecutive pairs. We do not control it directly, and we do not need to.
Why? Around the boundary between pair and pair , the sign pattern looks like:
The inside signs of neighboring pairs are opposite. So locally it is either:
or
That unknown middle sign can be whatever it wants. It is trapped between opposite signs, so it cannot help create four equal signs in a row. The longest dangerous streak gets broken constantly. Very rude to monotonic runs, which is exactly what we want.
Odd length
If is odd, after processing pairs one element remains. Take it from the left. This adds only one final comparison sign. Could that suddenly create four equal signs? No.
The last completed pair already has an internal sign, and the previous completed pair had the opposite internal sign, so near the end there is still a recent forced break. Appending one value cannot produce four equal signs unless the previous three signs were already equal, but our pair construction prevents that kind of unchecked run.
Algorithm
Maintain two pointers and .
For pair number :
Record L or R for every taken side.
If one element remains, take it.
The complexity is per test case, and overall. The implementation is tiny. Suspiciously tiny, even. But it works because the construction attacks the exact thing that makes an array bad: long runs of identical comparison signs.
#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);
for (int &x : p) cin >> x;
int l = 0, r = n - 1;
string ans;
int pairId = 0;
while (r - l + 1 >= 2) {
bool makeIncreasing = (pairId % 2 == 0);
if (makeIncreasing) {
if (p[l] < p[r]) {
ans += 'L';
++l;
ans += 'R';
--r;
} else {
ans += 'R';
--r;
ans += 'L';
++l;
}
} else {
if (p[l] > p[r]) {
ans += 'L';
++l;
ans += 'R';
--r;
} else {
ans += 'R';
--r;
ans += 'L';
++l;
}
}
++pairId;
}
if (l == r) ans += 'L';
cout << ans << '\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);
for (int &x : p) cin >> x;
int l = 0, r = n - 1;
string ans;
int pairId = 0;
while (r - l + 1 >= 2) {
bool makeIncreasing = (pairId % 2 == 0);
if (makeIncreasing) {
if (p[l] < p[r]) {
ans += 'L';
++l;
ans += 'R';
--r;
} else {
ans += 'R';
--r;
ans += 'L';
++l;
}
} else {
if (p[l] > p[r]) {
ans += 'L';
++l;
ans += 'R';
--r;
} else {
ans += 'R';
--r;
ans += 'L';
++l;
}
}
++pairId;
}
if (l == r) ans += 'L';
cout << ans << '\n';
}
}