PROBLEM LINK:
Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4
Author: raysh07
Tester: sushil2006
Editorialist: iceknight1093
DIFFICULTY:
Simple
PREREQUISITES:
None
PROBLEM:
You’re given a binary string S of length N+1.
Construct any array A of length N such that:
- 0 \le A_i \le N
- S_i = 1 if and only if some subarray of A has MEX equal to i.
It’s guaranteed that A_0 = A_1 = 1.
EXPLANATION:
There are several possible constructions - here is a relatively simple one.
Let’s start with A = [0, 1, 2, \ldots, N-1].
Observe that for this array:
- The prefix [0, 1, 2, \ldots, i] has a MEX of i+1.
- We can also obtain a MEX of 0 by taking the subarray [1], for example.
This array thus gives us every possible MEX from 0 to N.
Importantly, for any i \gt 0, note that the prefix [0, 1, \ldots, i-1] is the only subarray with a MEX of i.
Now, it might be the case that we don’t want all the MEX-es.
So, suppose we have S_i = 0 for some i.
One way to “turn off” the MEX of i, is to simply swap the values i and i-1.
That is, turn the array into A = [0, 1, 2, \ldots, i-2, \ \ \underline{i, i-1}, \ \ i+1, \ldots, N-1].
This ensures that i doesn’t appear as a prefix MEX, because once we have all the values 0, 1, 2, \ldots, i-1, we’ll also have to include i itself in the subarray - so the MEX becomes i+1 instead.
On the other hand, it can also be seen that this doesn’t change any of the other prefix MEX-es.
This idea easily generalizes to turning off any other MEX-es as well.
That is, we have the following:
- Start with A = [0, 1, 2, \ldots, N-1].
For convenience, we treat A as being 0-indexed, so that A_i = i initially. - Now, for each i such that S_i = 0 in order from left to right, simply swap A_i and A_{i-1}.
Note that A_{i-1} might not equal i-1 (because of a previous swap), but it will certainly be some value \lt i, and that’s enough for us.
This swap does the following:- The prefix ending at index i-1 now has the set of values \{0, 1, 2, \ldots, i-2, i\}, with a MEX of i-1.
Earlier, it used to have a MEX of i. - All other prefixes have exactly the same set of elements they had before; so their MEX-es don’t change.
This means we’ve exactly eliminated the MEX of i, while not affecting anything else.
- The prefix ending at index i-1 now has the set of values \{0, 1, 2, \ldots, i-2, i\}, with a MEX of i-1.
This allows us to eliminate all the MEX-es we don’t need, while retaining the ones we do need.
There is one edge case: since we’re just swapping elements, the MEX of the entire array will always remain N.
So, if S_N = 0, we need an additional step: set A_{N-1} = N, so that N doesn’t appear as a MEX.
One way of seeing this, is that we’re performing our swapping algorithm on the array A = [0, 1, \ldots, N] of length N+1, and then printing its first N elements.
This interpretation allows for an implementation that avoids having to casework out S_N = 0.
TIME COMPLEXITY:
\mathcal{O}(N) per testcase.
CODE:
Editorialist's code (PyPy3)
for _ in range(int(input())):
n = int(input())
s = input()
a = list(range(n+1))
for i in range(2, n+1):
if s[i] == '0':
a[i], a[i-1] = a[i-1], a[i]
print(*a[:n])