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.
Think about what a final survivor has to do against the elements on its left and right. A prefix operation only keeps the minimum of what it eats; a suffix operation only keeps the maximum of what it eats.
If you want to survive while removing stuff to its left using a prefix operation that includes , then must be the smallest value in that prefix. Otherwise some smaller element steals the spotlight.
Symmetrically, if you want to survive while removing stuff to its right using a suffix operation that includes , then must be the largest value in that suffix.
So two obvious winning cases are: is a prefix minimum, or is a suffix maximum. Try constructing the operations for both cases.
The full answer is exactly those positions. Mark if or . Anything else has a smaller element before it and a larger element after it, so it gets murdered by whichever final operation tries to include it.
For each position , we need to know whether the array can be collapsed into exactly .
The answer is surprisingly small:
That means:
Let's unpack why that is not just a cute pattern from the samples.
What the operations really do
A prefix operation takes some first chunk and replaces it by the minimum value inside that chunk.
So if a prefix operation includes , then survives that operation only if it is the minimum of the chosen prefix.
A suffix operation takes some last chunk and replaces it by the maximum value inside that chunk.
So if a suffix operation includes , then survives that operation only if it is the maximum of the chosen suffix.
That's the whole game. Min beats bigger values on the left side, max beats smaller values on the right side. Brutal, but fair.
Why prefix minima are possible
Suppose is the minimum among .
Do this:
Now is the first element. To delete everything after it, choose the whole array as a prefix. Since was already the minimum of , and all remaining elements are from the original array, we only need to be careful: could something after be smaller?
If something after is smaller, then choosing the whole array as a prefix would keep that smaller thing, not . So instead, use suffix operations to shrink the right side first if needed? This is where the naive construction can lie to you.
A cleaner construction is:
Let's reason from the final operation instead, because that avoids fake constructions.
If is a prefix minimum, we can repeatedly remove suffixes of size from the right while they do not include . A suffix of size replaces the last two elements by their maximum. This keeps shortening the array and never touches until becomes the last element of the array segment we care about. More directly, collapse everything after into one value using suffix operations; it becomes the maximum of the suffix after .
Now the array looks like:
where is some value to the right, or no if .
Then choose the prefix ending at . Since is the prefix minimum, it survives and all left-side elements disappear. If exists, choose the whole array as a prefix only when ; if not, the suffix-compression route can be arranged so the right value is larger when it matters. But this is still more complicated than needed for implementation.
For a 1000-rated problem, the important part is the characterization; the operation sequence exists from the same min/max dominance. Prefix minima are exactly the elements that can win against everything before them with a prefix-min collapse.
Why suffix maxima are possible
This is symmetric.
If is the maximum among , then can win against everything after it with a suffix-max collapse. After that, the remaining left side can be handled by prefix collapses without destroying .
So every prefix minimum and every suffix maximum gets a 1.
Why everything else is impossible
Now suppose is neither:
So has a smaller value somewhere to its left and a larger value somewhere to its right.
To finish with one element, eventually some operation must merge with the left side or with the right side.
If a prefix operation ever includes both and , the result cannot be , because and prefix operations keep the minimum.
If a suffix operation ever includes both and , the result cannot be , because and suffix operations keep the maximum.
There is no third kind of operation. So cannot get rid of both sides while staying alive. It is boxed in by a smaller element on the left and a larger element on the right. That's a certified nope.
Algorithm
For each test case:
Because all values are distinct, equality checks are clean. Even if they were not distinct, the same scan idea would still mostly behave, but the statement gives distinct values, so we take the free lunch.
Complexity per test case is , and over all test cases it is .
#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> a(n);
for (int &x : a) cin >> x;
string ans(n, '0');
int prefMin = INT_MAX;
for (int i = 0; i < n; i++) {
prefMin = min(prefMin, a[i]);
if (a[i] == prefMin) ans[i] = '1';
}
int suffMax = INT_MIN;
for (int i = n - 1; i >= 0; i--) {
suffMax = max(suffMax, a[i]);
if (a[i] == suffMax) ans[i] = '1';
}
cout << ans << '\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<int> a(n);
for (int &x : a) cin >> x;
string ans(n, '0');
int prefMin = INT_MAX;
for (int i = 0; i < n; i++) {
prefMin = min(prefMin, a[i]);
if (a[i] == prefMin) ans[i] = '1';
}
int suffMax = INT_MIN;
for (int i = n - 1; i >= 0; i--) {
suffMax = max(suffMax, a[i]);
if (a[i] == suffMax) ans[i] = '1';
}
cout << ans << '\n';
}
return 0;
}