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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

// 集合にデータを入れたい時
template <class T> struct UnionFind {
  vector<int> data;
  vector<T> val;
  UnionFind(int size) : data(size, -1), val(size) {
    REP(i, size) { val[i] = i; }
  }
  bool unionSet(int x, int y, T v) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
      val[x] = v;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
  T &value(int x) { return val[root(x)]; }
};

int p[100000];
char c[100000];
int a[100000];
bool v[100000];

int main() {
  int n, q;
  while (cin >> n >> q, n || q) {
    p[0] = -1;
    REP(i, n - 1) {
      cin >> p[i + 1];
      p[i + 1]--;
    }
    memset(v, 0, sizeof(v));
    v[0] = 1;
    REP(i, q) {
      cin >> c[i] >> a[i];
      a[i]--;
      if (c[i] == 'M') {
        if (v[a[i]])
          c[i] = '.';
        else
          v[a[i]] = 1;
      }
    }
    UnionFind<int> uf(n);
    REP(i, n) {
      if (!v[i]) {
        uf.unionSet(i, p[i], uf.value(p[i]));
      }
    }
    // REP(i,n) {
    //   cout << uf.value(i) << endl;
    // }
    ll ans = 0;
    for (int i = q - 1; i >= 0; --i) {
      if (c[i] == 'Q') {
        ans += uf.value(a[i]) + 1;
      } else if (c[i] == 'M') {
        uf.unionSet(a[i], p[a[i]], uf.value(p[a[i]]));
      }
    }
    cout << ans << endl;
  }
}

Error: WA

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

// 集合にデータを入れたい時
template <class T> struct UnionFind {
  vector<int> data;
  vector<T> val;
  UnionFind(int size) : data(size, -1), val(size) {}
  bool unionSet(int x, int y, T v) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
      val[x] = v;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
  T &value(int x) { return val[root(x)]; }
};

int p[100000];
char c[100000];
int a[100000];
bool v[100000];

int main() {
  int n, q;
  while (cin >> n >> q, n || q) {
    p[0] = -1;
    REP(i, n - 1) {
      cin >> p[i + 1];
      p[i + 1]--;
    }
    memset(v, 0, sizeof(v));
    v[0] = 1;
    REP(i, q) {
      cin >> c[i] >> a[i];
      a[i]--;
      if (c[i] == 'M') {
        if (v[a[i]])
          c[i] == '.';
        else
          v[a[i]] = 1;
      }
    }
    UnionFind<int> uf(n);
    REP(i, n) {
      if (!v[i]) {
        uf.unionSet(i, p[i], p[i]);
      }
    }
    ll ans = 0;
    for (int i = q - 1; i >= 0; --i) {
      if (c[i] == 'Q') {
        ans += uf.value(a[i]) + 1;
      } else if (c[i] == 'M') {
        uf.unionSet(a[i], p[a[i]], uf.value(p[a[i]]));
      }
    }
    cout << ans << endl;
  }
}