Problem p01288 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define int long long
using namespace std;
static const int MAX_N = 100000;
static const int inf = 1ll << 60;
static const int MAX_SEG = 1 << 17;
typedef pair<int, int> pii;
int dat[2 * MAX_SEG];

class segment {
public:
  int n;
  void init(int n_) {
    for (int i = 0; i < 2 * MAX_SEG - 1; ++i)
      dat[i] = 0;
  }
  void update(int a, int b, int x, int k = 0, int l = 0, int r = MAX_SEG) {
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      dat[k] = max(dat[k], x);
      return;
    }
    update(a, b, x, k * 2 + 1, l, (l + r) / 2);
    update(a, b, x, k * 2 + 2, (l + r) / 2, r);
  }
  int query(int k) {
    k += MAX_SEG - 1;
    int ret = dat[k];
    while (k) {
      k = (k - 1) / 2;
      ret = max(ret, dat[k]);
    }
    return ret;
  }
};

int N, M;
vector<int> g[MAX_N + 5];
int depth[MAX_N + 5];
int par[20][MAX_N];
int tin[2 * MAX_N + 5], tout[2 * MAX_N + 5];
int k = 0;

void dfs(int v, int p, int d) {
  par[0][v] = p;
  depth[v] = d;
  tin[v] = k++;
  for (int u = 0; u < g[v].size(); ++u) {
    dfs(g[v][u], v, d + 1);
    k++;
  }
  tout[v] = k;
}

void fill_table() {
  for (int i = 0; i < 19; i++) {
    for (int j = 0; j < N; j++) {
      if (par[i][j] == -1)
        par[i + 1][j] = -1;
      else
        par[i + 1][j] = par[i][par[i][j]];
    }
  }
}

signed main() {
  while (1) {
    int ans = 0;
    cin >> N >> M;
    if (N == 0 && M == 0)
      break;
    for (int i = 0; i < N; ++i)
      g[i].clear();
    memset(par, 0, sizeof(par));
    for (int i = 1; i < N; ++i) {
      int p;
      cin >> p;
      p--;
      g[p].PB(i);
    }
    k = 0;
    dfs(0, -1, 0);
    fill_table();
    segment seg;
    seg.init(N);
    for (int t = 0; t < M; ++t) {
      char que;
      int v;
      cin >> que;
      cin >> v;
      v--;
      // cout<<tin[v]<<" "<<tout[v]<<" "<<depth[v]<<endl;
      if (que == 'M') {
        seg.update(tin[v], tout[v], depth[v]);
      } else {
        int q = seg.query(tin[v]);
        for (int i = 19; i >= 0; --i) {
          if ((depth[v] - q) >> i & 1)
            v = par[i][v];
        }
        ans += v + 1;
      }
    }
    cout << ans << endl;
  }
}

Fixed submission:
#include <bits/stdc++.h>
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define int long long
using namespace std;
static const int MAX_N = 100000;
static const int inf = 1ll << 60;
static const int MAX_SEG = 1 << 17;
typedef pair<int, int> pii;
int dat[2 * MAX_SEG];

class segment {
public:
  int n;
  void init(int n_) {
    for (int i = 0; i < 2 * MAX_SEG - 1; ++i)
      dat[i] = 0;
  }
  void update(int a, int b, int x, int k = 0, int l = 0, int r = MAX_SEG) {
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      dat[k] = max(dat[k], x);
      return;
    }
    update(a, b, x, k * 2 + 1, l, (l + r) / 2);
    update(a, b, x, k * 2 + 2, (l + r) / 2, r);
  }
  int query(int k) {
    k += MAX_SEG - 1;
    int ret = dat[k];
    while (k) {
      k = (k - 1) / 2;
      ret = max(ret, dat[k]);
    }
    return ret;
  }
};

int N, M;
vector<int> g[MAX_N + 5];
int depth[MAX_N + 5];
int par[20][MAX_N];
int tin[2 * MAX_N + 5], tout[2 * MAX_N + 5];
int k = 0;

void dfs(int v, int p, int d) {
  par[0][v] = p;
  depth[v] = d;
  tin[v] = k++;
  for (int u = 0; u < g[v].size(); ++u) {
    dfs(g[v][u], v, d + 1);
    // k++;
  }
  tout[v] = k;
}

void fill_table() {
  for (int i = 0; i < 19; i++) {
    for (int j = 0; j < N; j++) {
      if (par[i][j] == -1)
        par[i + 1][j] = -1;
      else
        par[i + 1][j] = par[i][par[i][j]];
    }
  }
}

signed main() {
  while (1) {
    int ans = 0;
    cin >> N >> M;
    if (N == 0 && M == 0)
      break;
    for (int i = 0; i < N; ++i)
      g[i].clear();
    memset(par, 0, sizeof(par));
    for (int i = 1; i < N; ++i) {
      int p;
      cin >> p;
      p--;
      g[p].PB(i);
    }
    k = 0;
    dfs(0, -1, 0);
    fill_table();
    segment seg;
    seg.init(N);
    for (int t = 0; t < M; ++t) {
      char que;
      int v;
      cin >> que;
      cin >> v;
      v--;
      // cout<<tin[v]<<" "<<tout[v]<<" "<<depth[v]<<endl;
      if (que == 'M') {
        seg.update(tin[v], tout[v], depth[v]);
      } else {
        int q = seg.query(tin[v]);
        for (int i = 19; i >= 0; --i) {
          if ((depth[v] - q) >> i & 1)
            v = par[i][v];
        }
        ans += v + 1;
      }
    }
    cout << ans << endl;
  }
}