C - Lining Up 2 Editorial by en_translator
Consider the following sequence \((B _ i) _ {1\leq i\leq N}\):
\[B _ i=\left\lbrace\begin{matrix}j&(A _ j=i)\hphantom{\text{otherwise}}\\-1&(\text{otherwise})\hphantom{A _ j=i}\end{matrix}\right..\]
This sequence satisfies “behind person \(i\) is person \(B_i\) (or \(-1\) if no one is behind).”
Once we find these \(B _ i) _ {1\leq i\leq N}\), using \(x\) satisfying \(A _ x=-1\), the people in the line can be enumerated as person \(x,\) person \(B _ x,\) person \(B _ {B _ x},\) person \(B _ {B _ {B _ x}},\ldots,\) and person \(B _ {B _ {{}_{\ddots _ {B _ x}}}}\).
Thus, it is sufficient to find the sequence \((B _ i)\) and the frontmost person, and then appropriately repeat \(x\leftarrow B _ x\).
Sample code follows. We use the property that, if no one is behind person \(i\), the value \(B _ i\) can be freely chosen (as long as it does not collide with anything else).
#include <iostream>
#include <vector>
int main() {
using namespace std;
unsigned N;
cin >> N;
vector<unsigned> B(N, N); // B[i] := person behind person i (or N if nobody is behind)
unsigned front;
for(unsigned i = 0; i < N; ++i){
int A;
cin >> A;
--A; // Make it 0-based numbering
if(A < 0)
front = i;
else
B[A] = i; // Behind person i is person A ⇔ behind person A is person i
}
while(front < N){ // repeatedly inspect the person behind the current one, until it reaches N (=nobody is behind)
cout << front + 1 << " ";
front = B[front];
}
cout << endl;
return 0;
}
posted:
last update: