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

#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#define int ll

using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define per(i, b) for (ll i = b - 1; i >= 0; i--)
#define each(e, c) for (auto &e : c)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define lb lower_bound
#define ub upper_bound
#ifdef DEBUG
#define dump(...)                                                              \\
  (cerr << #__VA_ARGS__ << " = " << (DUMP(), __VA_ARGS__).str() << " ["        \\
        << __LINE__ << "]" << endl)
struct DUMP : ostringstream {
  template <class T> DUMP &operator,(const T &t) {
    if (this->tellp())
      *this << ", ";
    *this << t;
    return *this;
  }
};
#else
#define dump(...)
#endif

struct Node {
  int par;
  vi cs;
  Node(int p, vi const &cs) : par(p), cs(cs) {}
  Node() {}
};

vi ansester;
vi marked;

void update(vector<Node> &g, int v, int a) {
  ansester[v] = a;
  for (int c : g[v].cs) {
    if (!marked[c])
      update(g, c, a);
  }
}

int solve(vector<Node> g, vector<pair<char, int>> query) {
  ansester.assign(g.size() + 1, 1);
  marked.assign(g.size() + 1, 0);
  int ans = 0;
  rep(i, query.size()) {
    char q;
    int v;
    tie(q, v) = query[i];
    if (q == 'M') {
      update(g, v, v);
      marked[v] = true;
    } else {
      ans += ansester[v];
    }
  }
  return ans;
}

signed main() {
  int N, Q;
  while (cin >> N >> Q && N) {
    vector<Node> g(N + 1);
    rep(i, N - 1) {
      int x;
      cin >> x;
      g[i + 2].par = x;
      g[x].cs.eb(i + 2);
    }
    vi ignore(N + 1);
    vector<pair<char, int>> query;
    rep(i, Q) {
      char c;
      int v;
      cin >> c >> v;
      if (c == 'M') {
        if (!ignore[v]) {
          query.eb(c, v);
          ignore[v] = true;
        }
      } else {
        query.eb(c, v);
      }
    }
    cout << solve(g, query) << endl;
  }
}

Error: 0

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define per(i, b) for (ll i = b - 1; i >= 0; i--)
#define each(e, c) for (auto &e : c)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define lb lower_bound
#define ub upper_bound
#ifdef DEBUG
#define dump(...)                                                              \\
  (cerr << #__VA_ARGS__ << " = " << (DUMP(), __VA_ARGS__).str() << " ["        \\
        << __LINE__ << "]" << endl)
struct DUMP : ostringstream {
  template <class T> DUMP &operator,(const T &t) {
    if (this->tellp())
      *this << ", ";
    *this << t;
    return *this;
  }
};
#else
#define dump(...)
#endif

int const M = 1000100;

int N, Q;
int par[M];
vector<int> ch[M];
char q[M];
int v[M];
bool use[M];
bool flg[M];
int g[M];
bool marked[M];
int top[M]; // グループ→グループの根

// markを外すときにunionしていく。
// その際、グループ→グループの根の表を更新する

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)]; }
};

UnionFind uf(0);

void rec(int v) {
  for (int c : ch[v]) {
    if (marked[c]) {
      g[c] = c;
    } else {
      g[c] = g[v];
      uf.unionSet(c, v);
    }
    rec(c);
  }
}

int solve() {
  rep(i, N + 1) flg[i] = false;
  rep(i, Q) if (q[i] == 'M') {
    if (flg[v[i]])
      use[i] = false;
    else {
      use[i] = true;
      flg[v[i]] = true;
    }
  }
  marked[1] = true;
  per(i, Q) if (use[i]) { marked[v[i]] = true; }

  uf = UnionFind(N + 1);
  par[1] = 1;
  g[1] = 1;
  rec(1);

  rep(i, N + 1) if (i) { top[uf.root(i)] = g[i]; }

  int ans = 0;
  per(i, Q) if (use[i] || q[i] == 'Q') {
    if (q[i] == 'M') {
      top[uf.root(v[i])] = top[uf.root(par[v[i]])];
      uf.unionSet(v[i], par[v[i]]);
    } else {
      ans += top[uf.root(v[i])];
    }
  }
  return ans;
}

int main() {
  while (cin >> N >> Q && N) {
    rep(i, N - 1) {
      int v;
      cin >> v;
      par[i + 2] = v;
      ch[v].push_back(i + 2);
    }
    rep(i, Q) { cin >> q[i] >> v[i]; }
    cout << solve() << endl;
  }
}