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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < int(n); i++)

using namespace std;

// ?´?????????????????§????
struct UnionFind {
  // par[i]????????????i????±?????????¨??????????????????i ==
  // par[i]?????¨???????????????i?????¨?????????????????§??????
  vector<long long int> par;
  // sizes[i]???????????????i?????¨?????????????????????????????°???i?????????????????§????????´???????????????????????¨??????
  vector<long long int> sizes;

  UnionFind(long long int n) : par(n), sizes(n, 1) {
    // ???????????¨???????????????i?????°?????????i????????¨??????????????¨???????????????
    rep(i, n) par[i] = i;
  }

  // ?????????x????±?????????¨???????????????
  long long int find(long long int x) {
    if (x == par[x])
      return x;
    return par[x] = find(
               par[x]); // ????????????????????????????????°???????????????????????¢???
  }

  // 2???????????????x, y????±?????????¨??????????????????
  void unite(long long int x, long long int y) {
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    par[y] = x;
    sizes[x] += sizes[y];
  }

  bool same(long long int x, long long int y) { return find(x) == find(y); }

  int size(long long int x) { return sizes[find(x)]; }
};

int main() {
  long long int n, q;
  while (cin >> n >> q, n || q) {
    int a[100002];
    a[1] = 1;
    for (long long int i = 2; i <= n; i++) {
      cin >> a[i];
    }
    set<long long int> roots;
    roots.insert(1);
    vector<pair<char, long long int>> queries;
    for (long long int i = 0; i < q; i++) {
      char c;
      long long int v;
      cin >> c >> v;
      if (c == 'M' && roots.find(v) != roots.end())
        continue;
      if (c == 'M')
        roots.insert(v);
      queries.emplace_back(make_pair(c, v));
    }
    UnionFind uf(n + 2);
    for (long long int i = 2; i <= n; i++) {
      if (roots.find(i) == roots.end()) {
        // cout << a[i] << " - " << i << endl;
        uf.unite(a[i], i);
      }
    }
    long long int sum = 0;
    for (long long int i = (long long int)queries.size() - 1; i >= 0; i--) {
      // cout << queries[i].first << " " << queries[i].second << endl;
      if (queries[i].first == 'M') {
        uf.unite(a[queries[i].second], queries[i].second);
      }
      if (queries[i].first == 'Q') {
        // cout << uf.find(queries[i].second) << endl;
        sum += uf.find(queries[i].second);
      }
    }
    cout << sum << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    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)]; }
};

int main() {
  int n, q;
  while (cin >> n >> q, n || q) {
    int a[100002];
    for (int i = 2; i <= n; i++) {
      cin >> a[i];
    }
    map<int, int> roots;
    vector<pair<char, int>> queries;
    for (int i = 0; i < q; i++) {
      char c;
      int v;
      cin >> c >> v;
      if (roots.find(v) != roots.end())
        continue;
      if (c == 'M')
        roots[v] = a[v];
      queries.emplace_back(make_pair(c, v));
    }
    UnionFind uf(n + 2);
    for (int i = 2; i <= n; i++) {
      if (roots.find(i) == roots.end()) {
        uf.unionSet(a[i], i);
      }
    }
    long long int sum = 0;
    for (int i = q - 1; i >= 0; i--) {
      if (queries[i].first == 'M') {
        uf.unionSet(a[queries[i].second], queries[i].second);
      }
      if (queries[i].first == 'Q') {
        sum += uf.root(queries[i].second);
      }
    }
    cout << sum << endl;
  }
  return 0;
}