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

#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>
using namespace std;

using P = pair<char, int>;
struct union_find {
  vector<int> par;
  union_find(int n) {
    par = vector<int>(n);
    init(n);
  }
  void init(int n) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }
  void unite(int x, int y) { // y???????????????
    x = find(x);
    y = find(y);
    par[x] = y;
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
  int N, Q;
  while (cin >> N >> Q, N) {
    bool isMarked[100000];
    int parent[100000];
    fill(isMarked, isMarked + 100000, false);
    fill(parent, parent + 100000, 5000000);
    parent[0] = 0;
    for (int i = 1; i < N; i++) {
      int p;
      cin >> p;
      p--;
      parent[i] = p;
    }
    vector<P> V;
    isMarked[0] = true;
    for (int i = 0; i < Q; i++) {
      char C;
      int v;
      cin >> C >> v;
      v--;
      if (C == 'Q') {
        V.emplace_back(C, v);
      } else if (!isMarked[v]) {
        isMarked[v] = true;
        V.emplace_back(C, v);
      }
    }
    union_find UF(N);
    for (int i = 1; i < N; i++) {
      if (!isMarked[i])
        UF.unite(i, parent[i]);
    }

    reverse(V.begin(), V.end());
    int64_t ans = 0;
    for (auto p : V) {
      char C;
      int v;
      tie(C, v) = p;
      if (C == 'Q') {
        ans += UF.find(v) + 1;
      } else {
        if (v == 0)
          cout << 'A' << endl;
        isMarked[v] = false;
        UF.unite(v, parent[v]);
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>
using namespace std;

struct union_find {
  vector<int> par, rank;
  union_find(int n) {
    par = vector<int>(n);
    rank = vector<int>(n);
    init(n);
  }
  void init(int n) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
      rank[i] = 0;
    }
  }
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

vector<int> G[100000];
bool isMarked[100000];
int parent[100000];
using P = pair<char, int>;

void dfs1(int v, int pre, union_find &UF) {
  if (!isMarked[v])
    UF.unite(pre, v);
  for (auto to : G[v]) {
    if (to != pre)
      dfs1(to, v, UF);
  }
  return;
}

int main() {
  int N, Q;
  while (cin >> N >> Q, N) {
    for (auto &g : G)
      g.clear();
    fill(isMarked, isMarked + 100000, false);
    fill(parent, parent + 100000, -1);
    parent[0] = -1;
    for (int i = 1; i < N; i++) {
      int p;
      cin >> p;
      p--;
      parent[i] = p;
      G[p].push_back(i);
      G[i].push_back(p);
    }
    isMarked[0] = true;
    vector<P> V;
    for (int i = 0; i < Q; i++) {
      char C;
      int v;
      cin >> C >> v;
      v--;
      if (C == 'M')
        isMarked[v] = true;
      V.emplace_back(C, v);
    }
    reverse(V.begin(), V.end());
    union_find UF(N);
    dfs1(0, -1, UF);
    int ans = 0;
    for (auto p : V) {
      char C;
      int v;
      tie(C, v) = p;
      if (C == 'Q') {
        ans += UF.find(v);
      } else {
        UF.unite(v, parent[v]);
      }
    }
    cout << ans << endl;
  }
  return 0;
}