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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define REP2(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define REP(i, n) REP2(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define ITER(c) __typeof((c).begin())
#define PB(e) push_back(e)
#define FOREACH(i, c) for (ITER(c) i = (c).begin(); i != (c).end(); ++i)
#define MP(a, b) make_pair(a, b)
#define PARITY(n) ((n)&1)

typedef long long ll;
typedef pair<ll, ll> P;
const int INF = 1000 * 1000 * 1000 + 7;
const double EPS = 1e-10;

const int B = 400;

const int maxn = 100010;
int par[maxn];
vector<int> ch[maxn];

int V[maxn];
char QT[maxn];
int ancester[maxn];
bool use[maxn];
bool marked[maxn];

void compress(int l, int r) {
  vector<int> vs;

  memcpy(use, marked, sizeof(marked));
  REP2(i, l, r) use[V[i]] = true;

  queue<P> que;
  que.push(P(1, 0));
  ancester[1] = 0;

  while (!que.empty()) {
    int v = que.front().first;
    int a = que.front().second;
    que.pop();
    if (use[v] || marked[v])
      a = v;
    REP(i, ch[v].size()) {
      int to = ch[v][i];
      ancester[to] = a;
      que.push(P(to, a));
    }
  }
}

void mark(int v) { marked[v] = true; }

int calc(int v) {
  while (!marked[v])
    v = ancester[v];
  return v;
}

int main() {
  int N, Q;

  while (cin >> N >> Q && N + Q) {
    memset(par, 0, sizeof(par));
    memset(marked, false, sizeof(marked));

    REP(i, maxn) ch[i].clear();

    marked[1] = true;

    REP(i, N - 1) {
      cin >> par[i + 2];
      ch[par[i + 2]].push_back(i + 2);
    }

    REP(i, Q) { cin >> QT[i] >> V[i]; }

    ll s = 0;
    for (int l = 0; l < Q; l += B) {
      int r = min(l + B, Q);
      compress(l, r);
      REP2(i, l, r) {
        if (QT[i] == 'M')
          mark(V[i]);
        if (QT[i] == 'Q')
          s += calc(V[i]);
      }
    }
    cout << s << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define REP2(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define REP(i, n) REP2(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define ITER(c) __typeof((c).begin())
#define PB(e) push_back(e)
#define FOREACH(i, c) for (ITER(c) i = (c).begin(); i != (c).end(); ++i)
#define MP(a, b) make_pair(a, b)
#define PARITY(n) ((n)&1)

typedef long long ll;
typedef pair<ll, ll> P;
const int INF = 1000 * 1000 * 1000 + 7;
const double EPS = 1e-10;

const int B = 300;

const int maxn = 100010;
int par[maxn];
vector<int> ch[maxn];

int V[maxn];
char QT[maxn];
int ancester[maxn];
bool use[maxn];
bool marked[maxn];

void compress(int l, int r) {
  vector<int> vs;

  memcpy(use, marked, sizeof(marked));
  REP2(i, l, r) use[V[i]] = true;

  queue<P> que;
  que.push(P(1, 0));
  ancester[1] = 0;

  while (!que.empty()) {
    int v = que.front().first;
    int a = que.front().second;
    que.pop();
    if (use[v] || marked[v])
      a = v;
    REP(i, ch[v].size()) {
      int to = ch[v][i];
      ancester[to] = a;
      que.push(P(to, a));
    }
  }
}

void mark(int v) { marked[v] = true; }

int calc(int v) {
  v = par[v];
  while (!marked[v])
    v = ancester[v];
  return v;
}

int main() {
  int N, Q;

  while (cin >> N >> Q && N + Q) {
    memset(par, 0, sizeof(par));
    REP(i, maxn) ch[i].clear();

    marked[1] = true;

    REP(i, N - 1) {
      cin >> par[i + 2];
      ch[par[i + 2]].push_back(i + 2);
    }

    REP(i, Q) { cin >> QT[i] >> V[i]; }

    ll s = 0;
    for (int l = 0; l < Q; l += B) {
      int r = min(l + B, Q);
      compress(l, r);
      REP2(i, l, r) {
        if (QT[i] == 'M')
          mark(V[i]);
        if (QT[i] == 'Q')
          s += calc(V[i]);
      }
    }
    cout << s << endl;
  }
  return 0;
}