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

#include <bits/stdc++.h>

#define rep(n) for (int i = 0; i < n; i++)
#define repp(j, n) for (int j = 0; j < n; j++)
#define reppp(i, m, n) for (int i = m; i < n; i++)
#define all(c) c.begin(), c.end()
#define rall(c) c.rbegin(), c.rend()
#define debug(x) cerr << #x << ": " << x << endl

using namespace std;

typedef long long ll;
typedef pair<ll, ll> Pll;
typedef pair<int, int> Pii;

class UnionFind {
public:
  ll n;
  vector<ll> par;

  UnionFind(ll n) {
    rep(n) { par.push_back(ll(i)); }
  }

  ll find(ll x) { return ((par[x] == x) ? x : par[x] = find(par[x])); }

  void unite(ll x, ll y) {
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    par[y] = x;
    return;
  }

  bool is_same(ll x, ll y) { return find(x) == find(y); }
};

int main() {
  ll n, q, node;
  char c;
  cin >> n >> q;
  while (n || q) {
    vector<ll> parent(n + 1, 1), children[n + 1];
    reppp(i, 2, n + 1) {
      cin >> node;
      parent[i] = node;
      children[node].push_back(i);
    }

    vector<Pll> query;
    vector<bool> marked(n + 1, false);
    rep(q) {
      cin >> c >> node;
      if (c == 'Q') {
        query.emplace_back(1, node);
      } else {
        if (marked[node])
          continue;
        query.emplace_back(0, node);
        marked[node] = true;
      }
    }
    q = (ll)query.size();

    UnionFind uf = UnionFind(n + 1);
    reppp(i, 2, n + 1) {
      if (marked[i])
        continue;
      uf.unite(parent[i], i);
    }

    ll ans = 0;
    for (int i = q - 1; i >= 0; --i) {
      if (query[i].first) {
        ans += uf.find(query[i].second);
      } else {
        uf.unite(parent[query[i].second], query[i].second);
      }
    }
    cout << ans << endl;
    cin >> n >> q;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define rep(n) for (int i = 0; i < n; i++)
#define repp(j, n) for (int j = 0; j < n; j++)
#define reppp(i, m, n) for (int i = m; i < n; i++)
#define all(c) c.begin(), c.end()
#define rall(c) c.rbegin(), c.rend()
#define debug(x) cerr << #x << ": " << x << endl

using namespace std;

typedef long long ll;
typedef pair<ll, ll> Pll;
typedef pair<int, int> Pii;

class UnionFind {
public:
  int n;
  vector<int> par, rank;

  UnionFind(int n) {
    rep(n) {
      par.push_back(i);
      rank.push_back(0);
    }
  }

  int find(int x) { return ((par[x] == x) ? x : par[x] = find(par[x])); }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
    return;
  }

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

void dfs(ll node, ll marked_par, UnionFind uf, vector<bool> marked,
         vector<ll> children[]) {
  if (marked[node])
    marked_par = node;
  else
    uf.unite(marked_par, node);
  for (ll child : children[node]) {
    dfs(child, marked_par, uf, marked, children);
  }
}

int main() {
  ll n, q, node;
  char c;
  cin >> n >> q;
  while (n || q) {
    vector<ll> children[n + 1], parent(n + 1, 1);
    ll ans = 0;
    reppp(i, 2, n + 1) {
      cin >> node;
      children[node].push_back(i);
      parent[i] = node;
    }

    vector<Pll> query(q);
    vector<bool> marked(n + 1, false);
    rep(q) {
      cin >> c >> query[i].second;
      query[i].first = (c == 'Q' ? 1 : 0);
      if (c == 'M')
        marked[node] = true;
    }
    UnionFind uf = UnionFind(n + 1);
    dfs(1, 1, uf, marked, children);
    for (int i = q - 1; i >= 0; --i) {
      if (query[i].first) {
        ans += uf.find(node);
      } else {
        uf.unite(parent[node], node);
      }
    }
    cout << ans << endl;
    cin >> n >> q;
  }
}