Problem p02809 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <set>
#include <vector>
using namespace std;
using ll = long long;

template <class T> class RangeMin {
private:
  vector<T> seg;
  int n;

public:
  RangeMin(const vector<T> &v) : n(v.size()), seg(2 * v.size()) {
    for (int i = 0; i < n; ++i)
      seg[i + n] = v[i];
    for (int i = n - 1; i > 0; --i)
      seg[i] = min(seg[2 * i], seg[2 * i + 1]);
  }
  T get(int a, int b) const {
    T res = seg[a + n]; // Change to INF to allow a > b
    for (a += n, b += n + 1; a < b; a = (a + 1) / 2, b /= 2) {
      if (a & 1)
        res = min(res, seg[a]);
      if (b & 1)
        res = min(res, seg[b - 1]);
    }
    return res;
  }
  void set(int i, T v) {
    seg[i + n] = v;
    for (i += n; i > 1; i /= 2)
      seg[i / 2] = min(seg[i], seg[i ^ 1]);
  }
};

bool comp(const vector<int> &a, const vector<int> &b) {
  if (a.size() != b.size())
    return a.size() > b.size();
  for (int i = 0; i < a.size(); ++i) {
    if (a[i] != b[i])
      return a[i] < b[i];
  }
  return false;
}

vector<int> tryAll(vector<int> act, int b, const vector<int> &ban) {
  vector<int> res = {};
  for (auto x : act) {
    if (b == x)
      continue;

    vector<int> off = {x};
    vector<int> rem;
    for (auto v : act) {
      if (v != x)
        rem.push_back(v);
    }

    vector<int> app = tryAll(rem, ban[x], ban);
    for (auto v : app)
      off.push_back(v);
    if (!comp(res, off))
      res = off;
  }
  return res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;

  vector<pair<int, int>> ins(n);
  for (int i = 0; i < n; ++i)
    ins[i] = {0, i};

  vector<int> ban(n);
  for (int &p : ban) {
    cin >> p;
    --p;
    --ins[p].first;
  }
  RangeMin<pair<int, int>> rm(ins);

  if (n == 2) {
    cout << -1 << '\n';
  } else {
    // Lexicographically smallest such arrangement
    // If some card is banned by all other remaining cards, it must be next
    // Otherwise, all three-card setups are possible

    set<int> act;
    for (int i = 0; i < n; ++i)
      act.insert(i);

    vector<int> res(n - 3);
    for (int i = 0; i < n - 3; ++i) {
      int j = rm.get(0, n - 1).second;
      if (-ins[j].first < n - 1 - i) {
        auto it = act.begin();
        if (i > 0 && ban[res[i - 1]] == *it)
          ++it;
        j = *it;
        act.erase(it);
      } else {
        act.erase(act.find(j));
      }
      ++ins[ban[j]].first;
      rm.set(ins[ban[j]].second, ins[ban[j]]);
      rm.set(j, {n, -1});
      res[i] = j;
    }

    // Handle last three
    vector<int> rem;
    for (auto v : act)
      rem.push_back(v);
    int b = (n == 3 ? -1 : ban[res[n - 4]]);

    vector<int> lst = tryAll(rem, b, ban);

    for (auto i : res)
      cout << i + 1 << ' ';
    for (auto i : lst)
      cout << i + 1 << ' ';
    cout << '\n';
  }
}


Fixed submission:
#include <iostream>
#include <set>
#include <vector>
using namespace std;
using ll = long long;

template <class T> class RangeMin {
private:
  vector<T> seg;
  int n;

public:
  RangeMin(const vector<T> &v) : n(v.size()), seg(2 * v.size()) {
    for (int i = 0; i < n; ++i)
      seg[i + n] = v[i];
    for (int i = n - 1; i > 0; --i)
      seg[i] = min(seg[2 * i], seg[2 * i + 1]);
  }
  T get(int a, int b) const {
    T res = seg[a + n]; // Change to INF to allow a > b
    for (a += n, b += n + 1; a < b; a = (a + 1) / 2, b /= 2) {
      if (a & 1)
        res = min(res, seg[a]);
      if (b & 1)
        res = min(res, seg[b - 1]);
    }
    return res;
  }
  void set(int i, T v) {
    seg[i + n] = v;
    for (i += n; i > 1; i /= 2)
      seg[i / 2] = min(seg[i], seg[i ^ 1]);
  }
};

bool comp(const vector<int> &a, const vector<int> &b) {
  if (a.size() != b.size())
    return a.size() > b.size();
  for (int i = 0; i < a.size(); ++i) {
    if (a[i] != b[i])
      return a[i] < b[i];
  }
  return false;
}

vector<int> tryAll(vector<int> act, int b, const vector<int> &ban) {
  vector<int> res = {};
  for (auto x : act) {
    if (b == x)
      continue;

    vector<int> off = {x};
    vector<int> rem;
    for (auto v : act) {
      if (v != x)
        rem.push_back(v);
    }

    vector<int> app = tryAll(rem, ban[x], ban);
    for (auto v : app)
      off.push_back(v);
    if (!comp(res, off))
      res = off;
  }
  return res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;

  vector<pair<int, int>> ins(n);
  for (int i = 0; i < n; ++i)
    ins[i] = {0, i};

  vector<int> ban(n);
  for (int &p : ban) {
    cin >> p;
    --p;
    --ins[p].first;
  }
  RangeMin<pair<int, int>> rm(ins);

  if (n == 2) {
    cout << -1 << '\n';
  } else {
    // Lexicographically smallest such arrangement
    // If some card is banned by all other remaining cards, it must be next
    // Otherwise, all three-card setups are possible

    set<int> act;
    for (int i = 0; i < n; ++i)
      act.insert(i);

    vector<int> res(n - 3);
    for (int i = 0; i < n - 3; ++i) {
      int j = rm.get(0, n - 1).second;
      if (-ins[j].first < n - 1 - i) {
        auto it = act.begin();
        if (i > 0 && ban[res[i - 1]] == *it)
          ++it;
        j = *it;
        act.erase(it);
      } else {
        act.erase(act.find(j));
      }
      ++ins[ban[j]].first;
      if (act.find(ban[j]) != act.end()) {
        rm.set(ins[ban[j]].second, ins[ban[j]]);
      }
      rm.set(j, {n, -1});
      res[i] = j;
    }

    // Handle last three
    vector<int> rem;
    for (auto v : act)
      rem.push_back(v);
    int b = (n == 3 ? -1 : ban[res[n - 4]]);

    vector<int> lst = tryAll(rem, b, ban);

    for (auto i : res)
      cout << i + 1 << ' ';
    for (auto i : lst)
      cout << i + 1 << ' ';
    cout << '\n';
  }
}