Problem p01288 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <tuple>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

template <int N> struct UnionFind {
  int ig[N];
  int d[N];
  vector<int> gi[N];
  int dc;
  void init(int n = N) {
    for (int i = 0; i < n; ++i) {
      ig[i] = d[i] = i;
      gi[i] = {i};
    }
    dc = 0;
  }

  void merge(int a, int b) {
    if (same(a, b))
      return;
    dc++;
    int x = ig[a], y = ig[b];
    d[x] = d[y];
    if (gi[x].size() < gi[y].size())
      swap(x, y);
    for (int j : gi[y]) {
      ig[j] = x;
    }
    gi[x].insert(gi[x].end(), gi[y].begin(), gi[y].end());
    gi[y].clear();
  }

  bool same(int a, int b) { return ig[a] == ig[b]; }
  int get(int a) { return d[ig[a]]; }
};

const int MN = 100100;
P q[MN];
int root[MN];
bool ism[MN];
UnionFind<MN> uf;

int main() {
  while (true) {
    int n, m;
    scanf("%d %d\\n", &n, &m);
    if (!n)
      break;
    uf.init(n);
    fill_n(ism, n, false);
    ism[0] = true;
    for (int i = 1; i < n; i++) {
      int u;
      scanf("%d\\n", &u);
      u--;
      // assert(u < i);
      root[i] = u;
    }
    for (int i = 0; i < m; i++) {
      char c;
      int d;
      scanf(" %c %d\\n", &c, &d);
      d--;
      if (c == 'Q') {
        q[i] = P(0, d);
      } else {
        if (ism[d]) {
          q[i] = P(2, d);
        } else {
          ism[d] = true;
          q[i] = P(1, d);
        }
      }
    }
    for (int i = 0; i < n; i++) {
      if (ism[i])
        continue;
      uf.merge(i, root[i]);
    }
    ll res = 0;
    for (int i = m - 1; i >= 0; i--) {
      int a, b;
      tie(a, b) = q[i];
      if (a == 2)
        continue;
      if (a == 1) {
        uf.merge(b, root[b]);
      } else {
        res += uf.get(b) + 1;
      }
    }
    printf("%lld\\n", res);
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <tuple>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

template <int N> struct UnionFind {
  int ig[N];
  int d[N];
  vector<int> gi[N];
  int dc;
  void init(int n = N) {
    for (int i = 0; i < n; ++i) {
      ig[i] = d[i] = i;
      gi[i] = {i};
    }
    dc = 0;
  }

  void merge(int a, int b) {
    if (same(a, b))
      return;
    dc++;
    int x = ig[a], y = ig[b];
    if (gi[x].size() < gi[y].size())
      swap(x, y);
    for (int j : gi[y]) {
      ig[j] = x;
    }
    gi[x].insert(gi[x].end(), gi[y].begin(), gi[y].end());
    gi[y].clear();
    d[x] = min(d[x], d[y]);
  }

  bool same(int a, int b) { return ig[a] == ig[b]; }
  int get(int a) { return d[ig[a]]; }
};

const int MN = 100100;
P q[MN];
int root[MN];
bool ism[MN];
UnionFind<MN> uf;

int main() {
  while (true) {
    int n, m;
    scanf("%d %d\\n", &n, &m);
    if (!n)
      break;
    uf.init(n);
    fill_n(ism, n, false);
    ism[0] = true;
    for (int i = 1; i < n; i++) {
      int u;
      scanf("%d\\n", &u);
      u--;
      assert(u < i);
      root[i] = u;
    }
    for (int i = 0; i < m; i++) {
      char c;
      int d;
      scanf(" %c %d\\n", &c, &d);
      d--;
      if (c == 'Q') {
        q[i] = P(0, d);
      } else {
        if (ism[d]) {
          q[i] = P(2, d);
        } else {
          ism[d] = true;
          q[i] = P(1, d);
        }
      }
    }
    for (int i = 0; i < n; i++) {
      if (ism[i])
        continue;
      uf.merge(i, root[i]);
    }
    ll res = 0;
    for (int i = m - 1; i >= 0; i--) {
      int a, b;
      tie(a, b) = q[i];
      if (a == 2)
        continue;
      if (a == 1) {
        uf.merge(b, root[b]);
      } else {
        res += uf.get(b) + 1;
      }
    }
    printf("%lld\\n", res);
  }
  return 0;
}