Problem p02809 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

template <class G> class Fenwick_tree {
  vector<G> a;

public:
  Fenwick_tree(int n) : a(n) {}
  void add(int i, G val) {
    for (i++; i <= a.size(); i += i & -i)
      a[i - 1] += val;
  }
  G sum(int l, int r) const {
    if (l == 0) {
      G res{};
      for (; r > 0; r -= r & -r)
        res += a[r - 1];
      return res;
    }
    return sum(0, r) - sum(0, l);
  }
  int lower_bound(G val) const {
    if (val <= G{})
      return 0;
    int x = 0, k;
    for (k = 1; k <= a.size(); k <<= 1)
      ;
    for (k >>= 1; k > 0; k >>= 1)
      if (x + k <= a.size() && a[x + k - 1] < val)
        val -= a[x + k - 1], x += k;
    return x;
  }
  int upper_bound(G val) const {
    if (val < G{})
      return 0;
    int x = 0, k;
    for (k = 1; k <= a.size(); k <<= 1)
      ;
    for (k >>= 1; k > 0; k >>= 1)
      if (x + k <= a.size() && a[x + k - 1] <= val)
        val -= a[x + k - 1], x += k;
    return x;
  }
};

int n, bad[100000];

vector<pair<int, int>> V;

Fenwick_tree<int> F(0);
int ans[100000];

bool dfs(int i) {
  if (i == n)
    return true;
  // printf("i  = %d\n",i);

  int next = -1;
  for (auto p : V) {
    int deg = p.first, x = p.second;
    if (deg == n - 1 && F.sum(x, x + 1) == 1) {
      if (next != -1)
        return false;
      next = x;
    }
  }
  if (next != -1) {
    // printf("next = %d\n",next);
    int x = next;
    if (i == 0 || bad[ans[i - 1]] != x) {
      F.add(x, -1);
      ans[i] = x;
      for (auto &p : V)
        if (bad[x] != p.second)
          p.first++;
      if (dfs(i + 1))
        return true;
      for (auto &p : V)
        if (bad[x] != p.second)
          p.first--;
      F.add(x, 1);
    }
    return false;
  }

  for (int p = 1;; p++) {
    int x = F.lower_bound(p);
    if (x == n)
      break;
    if (i == 0 || bad[ans[i - 1]] != x) {
      F.add(x, -1);
      ans[i] = x;
      for (auto &p : V)
        if (bad[x] != p.second)
          p.first++;
      if (dfs(i + 1))
        return true;
      for (auto &p : V)
        if (bad[x] != p.second)
          p.first--;
      F.add(x, 1);
    }
  }
  return false;
}

int main() {
  scanf("%d", &n);
  rep(i, n) scanf("%d", &bad[i]), bad[i]--;

  if (n == 2)
    return puts("-1"), 0;

  F = Fenwick_tree<int>(n);
  rep(i, n) F.add(i, 1);

  vector<int> deg(n);
  rep(i, n) deg[bad[i]]++;
  vector<pair<int, int>> p(n);

  rep(i, n) p[i] = {-deg[i], i};
  sort(p.begin(), p.end());
  rep(i, min(500, n)) V.emplace_back(-p[i].first, p[i].second);
  // for(auto q:V) printf("%d %d\n",q.first,q.second);

  bool ok = dfs(0);

  if (ok) {
    rep(i, n) printf("%d%c", ans[i] + 1, i < n - 1 ? ' ' : '\n');
  } else {
    puts("-1");
  }

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

template <class G> class Fenwick_tree {
  vector<G> a;

public:
  Fenwick_tree(int n) : a(n) {}
  void add(int i, G val) {
    for (i++; i <= a.size(); i += i & -i)
      a[i - 1] += val;
  }
  G sum(int l, int r) const {
    if (l == 0) {
      G res{};
      for (; r > 0; r -= r & -r)
        res += a[r - 1];
      return res;
    }
    return sum(0, r) - sum(0, l);
  }
  int lower_bound(G val) const {
    if (val <= G{})
      return 0;
    int x = 0, k;
    for (k = 1; k <= a.size(); k <<= 1)
      ;
    for (k >>= 1; k > 0; k >>= 1)
      if (x + k <= a.size() && a[x + k - 1] < val)
        val -= a[x + k - 1], x += k;
    return x;
  }
  int upper_bound(G val) const {
    if (val < G{})
      return 0;
    int x = 0, k;
    for (k = 1; k <= a.size(); k <<= 1)
      ;
    for (k >>= 1; k > 0; k >>= 1)
      if (x + k <= a.size() && a[x + k - 1] <= val)
        val -= a[x + k - 1], x += k;
    return x;
  }
};

int n, bad[100000];

vector<pair<int, int>> V;

Fenwick_tree<int> F(0);
int ans[100000];

bool dfs(int i) {
  if (i == n)
    return true;
  // printf("i  = %d\n",i);

  int next = -1;
  for (auto p : V) {
    int deg = p.first, x = p.second;
    if (deg == n - 1 && F.sum(x, x + 1) == 1) {
      if (next != -1)
        return false;
      next = x;
    }
  }
  if (next != -1) {
    // printf("next = %d\n",next);
    int x = next;
    if (i == 0 || bad[ans[i - 1]] != x) {
      F.add(x, -1);
      ans[i] = x;
      for (auto &p : V)
        if (bad[x] != p.second)
          p.first++;
      if (dfs(i + 1))
        return true;
      for (auto &p : V)
        if (bad[x] != p.second)
          p.first--;
      F.add(x, 1);
    }
    return false;
  }

  for (int p = 1;; p++) {
    int x = F.lower_bound(p);
    if (x == n)
      break;
    if (i == 0 || bad[ans[i - 1]] != x) {
      F.add(x, -1);
      ans[i] = x;
      for (auto &p : V)
        if (bad[x] != p.second)
          p.first++;
      if (dfs(i + 1))
        return true;
      for (auto &p : V)
        if (bad[x] != p.second)
          p.first--;
      F.add(x, 1);
    }
  }
  return false;
}

int main() {
  scanf("%d", &n);
  rep(i, n) scanf("%d", &bad[i]), bad[i]--;

  if (n == 2)
    return puts("-1"), 0;

  F = Fenwick_tree<int>(n);
  rep(i, n) F.add(i, 1);

  vector<int> deg(n);
  rep(i, n) deg[bad[i]]++;
  vector<pair<int, int>> p(n);

  rep(i, n) p[i] = {-deg[i], i};
  sort(p.begin(), p.end());
  rep(i, min(300, n)) V.emplace_back(-p[i].first, p[i].second);
  // for(auto q:V) printf("%d %d\n",q.first,q.second);

  bool ok = dfs(0);

  if (ok) {
    rep(i, n) printf("%d%c", ans[i] + 1, i < n - 1 ? ' ' : '\n');
  } else {
    puts("-1");
  }

  return 0;
}