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

#include <bits/stdc++.h>

using namespace std;

#define MAX (1 << 17)
#define INF (1LL << 55)
typedef long long ll;
typedef pair<ll, ll> P;

struct SegmetTree {
  int n;
  P dat[2 * MAX - 1];

  SegmetTree(int n_) {
    n = 1;
    while (n < n_) {
      n *= 2;
    }
    for (int i = 0; i < 2 * n - 1; i++) {
      dat[i] = P(0, 1);
    }
  }

  ll get_nearest_marked_node(int k) {
    k += n - 1;
    P p = dat[k];
    while (k > 0) {
      k = (k - 1) / 2;
      p = max(p, dat[k]);
    }
    return p.second;
  }

  void mark(int a, int b, int k, int l, int r, P x) {
    if (r <= a || b <= l)
      return;

    if (a <= l && r <= b) {
      dat[k] = max(dat[k], x);
    } else {
      mark(a, b, k * 2 + 1, l, (l + r) / 2, x);
      mark(a, b, k * 2 + 2, (l + r) / 2, r, x);
    }
  }
};

ll L[MAX], R[MAX], D[MAX], p;
vector<int> G[MAX];

void init(int N) {
  p = 0;
  for (int i = 0; i < N; i++) {
    G[i].clear();
  }
}

void dfs(int v, int depth) {
  L[v] = p++;
  D[v] = depth;
  for (int i = 0; i < (int)G[v].size(); i++) {
    dfs(G[v][i], depth + 1);
  }
  R[v] = p;
}

int main() {
  int N, Q, x;
  while (cin >> N >> Q, N) {
    init(N);
    for (int i = 1; i < N; i++) {
      cin >> x;
      x--;
      G[x].push_back(i);
    }

    dfs(0, 0);

    SegmetTree st(N);

    char m;
    ll v, res = 0;
    while (Q--) {
      cin >> m >> v;
      v--;
      if (m == 'M') {
        st.mark(L[v], R[v], 0, 0, st.n, P(D[v], v + 1));
      } else {
        res += st.get_nearest_marked_node(L[v]);
      }
    }
    cout << res << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define MAX (1 << 17)
#define INF (1 << 29)

struct SegmetTree {
  int n, dat[2 * MAX - 1];

  SegmetTree(int n_, vector<int> &d) {
    n = 1;
    while (n < n_) {
      n *= 2;
    }
    for (int i = 0; i < 2 * n - 1; i++) {
      dat[i] = 1;
    }
  }

  void update(int k, int a) {
    k += n - 1;
    dat[k] = max(dat[k], a);
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = max(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  int get_max(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return -INF;

    if (a <= l && r <= b) {
      return dat[k];
    } else {
      int vl = get_max(a, b, k * 2 + 1, l, (l + r) / 2);
      int vr = get_max(a, b, k * 2 + 2, (l + r) / 2, r);
      return max(vl, vr);
    }
  }
};

int child[MAX];
vector<int> G[MAX], vec;

void init(int N) {
  vec.clear();
  for (int i = 0; i < N; i++) {
    G[i].clear();
    child[i] = 0;
  }
}

int dfs(int v) {
  int c = 0;
  vec.push_back(v);
  for (int i = 0; i < (int)G[v].size(); i++) {
    c += dfs(G[v][i]) + 1;
  }
  return (child[v] = c);
}

int main() {
  int N, Q, x;
  while (cin >> N >> Q, N) {
    init(N);
    for (int i = 1; i < N; i++) {
      cin >> x;
      x--;
      G[x].push_back(i);
    }

    dfs(0);

    vector<int> num(N);
    for (int i = 0; i < (int)vec.size(); i++) {
      num[vec[i]] = i;
    }

    SegmetTree st(N, vec);

    char m;
    int v, res = 0;
    while (Q--) {
      cin >> m >> v;
      v--;
      if (m == 'M') {
        for (int i = num[v]; i <= num[v] + child[v]; i++) {
          st.update(i, v + 1);
        }
      } else {
        int n = num[v];
        res += st.get_max(n, n + child[v] + 1, 0, 0, st.n);
      }
    }
    cout << res << endl;
  }
  return 0;
}