Official

E - Find it! Editorial by en_translator


In fact, the answer can be found by the following procedure.

  • Initially, prepare an empty sequence \(S\).
  • Then, starting from an arbitrary vertex \(v\), repeat the following:
    • If \(S\) does not contain \(v\)
      • Push \(v\) to the tail of \(S\), and travel from \(v\) to \(A_v\) along the edge \(v \rightarrow A_v\).
    • If \(S\) contains \(v\)
      • Suppose that \(S = (x_1, x_2, \dots, v, y_1, y_2,\dots, y_k)\).
      • Then, \((v, y_1, y_2, \dots, y_k)\) can be the answer.
      • This is because there are edges \(v \rightarrow y_1, y_i \rightarrow y_{i+1}\)(\(1 \le i \le k-1\)), as well as \(y_k \rightarrow v\), which form a cycle.

By the constraints of the problem, every vertex has an outgoing edge, so this procedure always yields an answer.

By determining if \(S\) contains \(v\) in manner of packet sort, the problem can be solved in a time complexity of \(O(N)\).

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  int n;
  cin >> n;
  vector<int> a(n+1);
  for(int i=1;i<=n;i++){
    cin >> a[i];
  }

  vector<int> fl(n+1,0),s;
  int v=1; // any vertex is ok to start
  while(fl[v]==0){
    fl[v]=1;
    s.push_back(v);
    v=a[v];
  }

  vector<int> res;
  for(auto &nx : s){
    if(nx==v){v=-1;}
    if(v==-1){res.push_back(nx);}
  }
  cout << res.size() << "\n";
  for(int i=0;i<res.size();i++){
    if(i){cout << " ";}
    cout << res[i];
  }cout << "\n";
  return 0;
}

posted:
last update: