E - 列の復元 / Restoring the Sequence 解説 by admin 印刷ページ
gpt-6-astra-mediumOverview
We reconstruct the original line from \(A_x\), the “number of people taller than themselves standing in front of them” for each height \(x\).
We can reconstruct it by placing people in ascending order of height into the \((A_x+1)\)-th available position from the front, and we use a Fenwick Tree (BIT) to manage the available positions.
Analysis
Placing People in Ascending Order of Height
Initially, prepare \(N\) empty slots for the answer line. Then, consider placing people in the order of heights \(1,2,\dots,N\).
At the moment we place the person of height \(x\):
- All people already placed have heights strictly less than \(x\).
- After placing \(x\), all remaining empty slots will be filled by people taller than \(x\).
Therefore, the number of taller people standing in front of the person of height \(x\) is equal to the number of empty slots remaining before the position where \(x\) is placed.
To make this count equal to \(A_x\), we see that we should place the person of height \(x\) at the \((A_x+1)\)-th empty slot from the front.
Concrete Example
Consider the case where \(N=4\) and \(A=(2,0,1,0)\). Denoting an empty slot as □, they can be placed as follows:
| Height to place \(x\) | \(A_x\) | Chosen empty slot | Line after placement |
|---|---|---|---|
| \(1\) | \(2\) | \(3\)rd from front | □ □ 1 □ |
| \(2\) | \(0\) | \(1\)st from front | 2 □ 1 □ |
| \(3\) | \(1\) | \(2\)nd from front | 2 □ 1 3 |
| \(4\) | \(0\) | \(1\)st from front | 2 4 1 3 |
For example, people of heights \(2\) and \(4\) are in front of the person of height \(1\), which matches the record \(A_1=2\).
Finding Empty Slots Efficiently
If we scan the line from the front to count empty slots every time, placing one person takes up to \(O(N)\) time. This would take \(O(N^2)\) overall, which is too slow for \(N \le 2\times 10^5\).
Therefore, we maintain the following values for each position using a Fenwick Tree:
- Empty position: \(1\)
- Occupied position: \(0\)
Here, the prefix sum up to a certain position represents the number of empty slots in that range. By using binary lifting on the Fenwick Tree, we can find the \(k\)-th empty slot from the front in \(O(\log N)\) time.
Algorithm
- Prepare an array
ansto store the answer. - Construct a Fenwick Tree representing the state where all positions are empty, i.e., each position has a value of \(1\).
- For each \(x=1,2,\dots,N\) in order, perform the following:
- Set \(k=A_x+1\).
- Using the Fenwick Tree, find the \(k\)-th empty slot from the front.
- Place the person of height \(x\) at that position.
- Update the value at that position from \(1\) to \(0\).
- Output
ans.
How to Find the \(k\)-th Empty Slot with a Fenwick Tree
The desired position is “the first position where the prefix sum is at least \(k\).”
In the code, we search for pos, which is the position immediately preceding it—that is, “the largest position where the prefix sum is strictly less than \(k\).”
Starting with step as the largest power of \(2\) less than or equal to \(N\) and halving it successively, we perform the following:
- Consider
nxt = pos + stepas a candidate. - If
nxt <= nandbit[nxt] < k, even skipping this entire range is not enough to reach the target empty slot. - In that case, update
pos = nxtand subtract the number of empty slots in the skipped range fromk.
With this search order, bit[nxt] represents the number of empty slots in the range being considered for skipping. After the search finishes, the target position in 1-based indexing is pos + 1.
Correctness
When placing the person of height \(x\), choosing the \((A_x+1)\)-th empty slot from the front ensures that there are exactly \(A_x\) empty slots before them.
Those slots will definitely be filled later by people taller than \(x\). On the other hand, all people already placed are shorter than \(x\), so they are not included in the count \(A_x\).
Thus, the final number of taller people standing in front of the person of height \(x\) will be exactly \(A_x\). Since this holds for all \(x\), the reconstructed line satisfies the condition.
Furthermore, there are \(N-x+1\) empty slots at the time of placing \(x\), and by the constraints \(1 \le A_x+1 \le N-x+1\), the chosen position is guaranteed to exist.
Complexity
- Time Complexity: \(O(N\log N)\)
- Space Complexity: \(O(N)\)
For each person, finding the empty slot and updating the Fenwick Tree both take \(O(\log N)\) time.
Implementation Details
Initializing the Fenwick Tree in \(O(N)\)
bit[i]stores the sum of the interval ending at position \(i\) with lengthi & -i. Since each position initially has a value of \(1\), it can be initialized directly as:bit = [i & -i for i in range(n + 1)]Watch Out for Indexing Differences
The Fenwick Tree is 1-indexed, whileansis 0-indexed. Since the target position found on the Fenwick Tree ispos + 1, the assignment to the answer array isans[pos] = x.Search Condition is
bit[nxt] < k
Ifbit[nxt] == k, the desired empty slot lies within that interval. You must not skip the entire interval.Subtract \(1\) from the Placed Position
Add \(-1\) to the corresponding position in the Fenwick Tree so that the occupied position is no longer counted as an empty slot.Source Code
import sys
def main():
data = list(map(int, sys.stdin.buffer.read().split()))
n = data[0]
bit = [i & -i for i in range(n + 1)]
ans = [0] * n
highest_bit = 1 << (n.bit_length() - 1)
for x in range(1, n + 1):
k = data[x] + 1
pos = 0
step = highest_bit
while step:
nxt = pos + step
if nxt <= n and bit[nxt] < k:
k -= bit[nxt]
pos = nxt
step >>= 1
ans[pos] = x
idx = pos + 1
while idx <= n:
bit[idx] -= 1
idx += idx & -idx
sys.stdout.write(" ".join(map(str, ans)) + "\n")
if __name__ == "__main__":
main()
This editorial was generated by gpt-6-astra-medium.
投稿日時:
最終更新: