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 a fixed value , don't think about probabilities. "Always stable" means an adversary can choose the worst possible midpoint every single time.
Let be where value sits in the permutation. If the search ever picks an index left of , what must be true about that value so the interval still keeps ?
That gives the exact condition: every index left of must contain a value , and every index right of must contain a value .
Because there are exactly values smaller than , the previous condition forces . So the stable values are exactly the positions where and all smaller values are before them / all larger values after them.
Build the permutation by splitting the values into maximal blocks of equal characters in . A block of 1s must stay fixed. A block of 0s can be made unstable by rotating its values by one, but only if its length is at least . So the only impossible case is a lonely 0 block of length .
Let's pin down what "stable" actually means, because the random midpoint is a distraction. Random? Nah. Since must work for every possible choice of midpoint, we should treat the midpoint choices as hostile.
Suppose value is placed at position .
During the search, if the current interval still contains and we choose some midpoint :
Since the first midpoint can be any position from to , this condition must already hold globally:
and
That is the whole game.
Key Consequence
There are exactly values smaller than . If all positions before contain values smaller than , then there can be at most such positions:
So .
Similarly, all positions after must contain values larger than . There are exactly larger values, so:
which gives .
Therefore:
So if is stable, it must be sitting at its own index. More strongly, the prefix before it must be exactly the smaller values and the suffix after it must be exactly the larger values. In permutation language, stable values are fixed points that are also valid split points.
How to Construct the Exact Pattern
Now look at the target string .
If , we want value stable. The easiest way is to leave .
If , we want value unstable. The easiest way is to make sure by moving it somewhere else.
But we must not accidentally break the stable 1 values. Since a stable value needs all smaller values on the left and all larger values on the right, we cannot move values across a 1 position. A 1 acts like a wall: values less than it stay left, values greater than it stay right.
So the permutation naturally splits into maximal consecutive blocks of equal characters in :
1s, keep everything fixed.0s, rotate the values inside that block by one position.Example: positions are all 0. Put
This keeps all values inside the same block, so it does not cross any 1 wall. Every position in the block changes value, so every zero value becomes unstable.
When Is It Impossible?
A 0 block of length is fatal.
If position is a lone zero, then both neighbors, if they exist, are 1 walls. Value cannot move left or right without crossing a stable value's boundary. But if , then is stable. So there is no way out. Tiny block, big pain.
So the condition is simple:
Every maximal block of
0s must have length at least .
If that holds, rotate each zero block and leave one blocks fixed. Done.
#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;
string s;
cin >> n >> s;
vector<int> p(n + 1);
iota(p.begin(), p.end(), 0);
bool ok = true;
for (int i = 1; i <= n; ) {
int j = i;
while (j <= n && s[j - 1] == s[i - 1]) j++;
if (s[i - 1] == '0') {
int len = j - i;
if (len == 1) {
ok = false;
break;
}
for (int k = i; k < j - 1; k++) p[k] = k + 1;
p[j - 1] = i;
}
i = j;
}
if (!ok) {
cout << "NO\n";
continue;
}
cout << "YES\n";
for (int i = 1; i <= n; i++) {
cout << p[i] << (i == n ? '\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;
string s;
cin >> n >> s;
vector<int> p(n + 1);
iota(p.begin(), p.end(), 0);
bool ok = true;
for (int i = 1; i <= n; ) {
int j = i;
while (j <= n && s[j - 1] == s[i - 1]) j++;
if (s[i - 1] == '0') {
int len = j - i;
if (len == 1) {
ok = false;
break;
}
for (int k = i; k < j - 1; k++) p[k] = k + 1;
p[j - 1] = i;
}
i = j;
}
if (!ok) {
cout << "NO\n";
continue;
}
cout << "YES\n";
for (int i = 1; i <= n; i++) {
cout << p[i] << (i == n ? '\n' : ' ');
}
}
}