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

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct UnionFind {
  int parent[110000];
  void unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) {
      return;
    }
    parent[y] = x;
  }
  int findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return parent[x] < 0 ? x : parent[x] = root(parent[x]); }
};

int n, q;
UnionFind ufind;
int parent[110000];
bool mark[110000];
int query[110000];

int main() {
  while (scanf("%d %d", &n, &q), n | q) {
    memset(&ufind, -1, sizeof(ufind));
    MEMSET(mark, false);
    parent[0] = 0;
    REP(i, n - 1) {
      int p;
      scanf("%d", &p);
      parent[i + 1] = p - 1;
    }
    int m = 0;
    REP(i, q) {
      char c;
      int v;
      scanf(" %c %d", &c, &v);
      if (c == 'Q') {
        query[m++] = v;
      } else if (c == 'M' && !mark[v - 1]) {
        mark[v - 1] = true;
        query[m++] = -v;
      }
    }
    REP(i, n) {
      if (mark[i]) {
        continue;
      }
      ufind.unionSet(parent[i], i);
    }
    reverse(query, query + m);
    ll ans = 0;
    REP(i, m) {
      int index = abs(query[i]) - 1;
      if (query[i] > 0) {
        ans += ufind.root(index) + 1;
      } else {
        ufind.unionSet(parent[index], index);
      }
    }
    printf("%lld\\n", ans);
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct UnionFind {
  int parent[110000];
  void unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) {
      return;
    }
    parent[y] = x;
  }
  int findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return parent[x] < 0 ? x : parent[x] = root(parent[x]); }
};

int n, q;
UnionFind ufind;
int parent[110000];
bool mark[110000];
int query[11000];

int main() {
  while (scanf("%d %d", &n, &q), n | q) {
    memset(&ufind, -1, sizeof(ufind));
    MEMSET(mark, false);
    parent[0] = 0;
    REP(i, n - 1) {
      int p;
      scanf("%d", &p);
      parent[i + 1] = p - 1;
    }
    int m = 0;
    REP(i, q) {
      char c;
      int v;
      scanf(" %c %d", &c, &v);
      if (c == 'Q') {
        query[m++] = v;
      } else if (c == 'M' && !mark[v - 1]) {
        mark[v - 1] = true;
        query[m++] = -v;
      }
    }
    REP(i, n) {
      if (mark[i]) {
        continue;
      }
      ufind.unionSet(parent[i], i);
    }
    reverse(query, query + m);
    ll ans = 0;
    REP(i, m) {
      int index = abs(query[i]) - 1;
      if (query[i] > 0) {
        ans += ufind.root(index) + 1;
      } else {
        ufind.unionSet(parent[index], index);
      }
    }
    printf("%lld\\n", ans);
  }
}