Problem p01288 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define all(n) n.begin(), n.end()
#define each(i, n) for (auto &i : n)
typedef long long ll;

const int INF = 1e9;

int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

struct UnionFind {
  vector<int> data;
  vector<int> to;
  UnionFind(int size) : data(size, -1), to(size, -1) { rep(i, size) to[i] = i; }
  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;
  }
  void setTo(int x, int to) { this->to[root(x)] = to; }
  int findTo(int x) { return to[root(x)]; }
  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)]; }
};

signed main() {

  int n, q;
  while (cin >> n >> q && n) {
    struct edge {
      int p, m;
      int count;
      vector<int> t;
    };

    vector<edge> e(n);
    for (int i = 1; i < n; i++) {
      cin >> e[i].p;
      e[i].p--;
      e[i].m = -1;
      e[i].count = 0;
      e[e[i].p].t.push_back(i);
    }
    e[0].m = 0;
    e[0].count = 1;

    vector<int> v(q);
    vector<char> c(q);
    rep(i, q) {
      cin >> c[i] >> v[i];
      v[i]--;
      if (c[i] == 'M') {
        e[v[i]].m = v[i];
        e[v[i]].count++;
      }
    }
    function<void(int, int)> dfs = [&](int a, int b) {
      if (e[a].m == -1) {
        e[a].m = b;
      }
      rep(i, e[a].t.size()) { dfs(e[a].t[i], e[a].m); }
    };
    dfs(0, 0);
    ll ans = 0;
    UnionFind uf(n);

    for (int i = q - 1; i >= 0; i--) {
      int j = v[i];
      if (c[i] == 'M') {
        e[j].count--;
        if (e[j].count == 0) {
          int root = uf.findTo(e[e[j].p].m);
          uf.unionSet(e[j].m, e[e[j].p].m);
          uf.setTo(e[j].m, root);
        }
      } else {
        ans += uf.findTo(e[j].m) + 1;
      }
    }

    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define all(n) n.begin(), n.end()
#define each(i, n) for (auto &i : n)
typedef long long ll;

const int INF = 1e9;

int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

signed main() {

  int n, q;
  while (cin >> n >> q && n) {
    struct edge {
      int p, m;
      int count;
      vector<int> t;
    };

    vector<edge> e(n + 1);
    for (int i = 1; i < n; i++) {
      cin >> e[i].p;
      e[i].p--;
      e[i].m = -1;
      e[i].count = 0;
      e[e[i].p].t.push_back(i);
    }
    e[0].m = 0;
    e[0].count = -1;

    vector<int> v(q);
    vector<char> c(q);
    rep(i, q) {
      cin >> c[i] >> v[i];
      if (c[i] == 'M') {
        e[v[i]].m = --v[i];
        e[v[i]].count++;
      }
    }
    function<void(int, int)> dfs = [&](int a, int b) {
      if (e[a].m == -1) {
        e[a].m = b;
      }
      rep(i, e[a].t.size()) { dfs(e[a].t[i], e[a].m); }
    };
    dfs(0, 0);
    vector<int> tb(n);
    rep(i, n) tb[i] = i;
    ll ans = 0;

    for (int i = q - 1; i >= 0; i--) {
      int j = v[i];
      if (c[i] == 'M') {
        e[j].count--;
        if (e[j].count == 0) {
          tb[e[j].m] = e[e[j].p].m;
        }
      } else {
        int to = e[j].m;
        while (tb[to] != to) {
          to = tb[to];
        }
        int last = to;
        to = e[j].m;
        while (tb[to] != to) {
          tb[to] = last;
          to = tb[to];
        }
        ans += tb[to] + 1;
      }
    }

    cout << ans << endl;
  }

  return 0;
}