Problem p01288 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i < n; i++)
#define int long long
using namespace std;
const int INF = 1e9;
typedef pair<int, int> P;
const int MAX_V = 100010;
const int MAX_LOG_V = 30;

struct BIT {
  int N;
  vector<int> dat;
  BIT() {}
  BIT(int n) {
    N = n;
    dat.resize(N + 1);
  }
  // update k th element (0-index)
  void add(int k, int x) {
    k++;
    while (k <= N) {
      dat[k] += x;
      k += k & -k;
    }
  }
  // sum [0, k) (0-index)
  int sum(int k) {
    int s = 0;
    while (k > 0) {
      s += dat[k];
      k -= k & -k;
    }
    return s;
  }
  // sum [a, b) (0-index)
  int query(int a, int b) { return sum(b) - sum(a); }
};

int n, q;
vector<int> G[MAX_V];

class Euler_Tour {
public:
  // vector<vector<int> > g;
  // begin[v],end[v]はそれぞれvがオイラーツアー上で最初と最後に現れるインデックス
  //[begin[v], end[v])がvを根とする部分木 (半開区間に注意)
  vector<int> euler_tour, begin, end, dist;
  Euler_Tour(int n) : /*g(n),*/ begin(2 * n), end(2 * n){};
  int k = 0, root = 0;
  void dfs(int curr, int par) {
    begin[curr] = k;
    euler_tour.push_back(curr);
    k++;
    for (auto next : G[curr]) {
      if (next == par)
        continue;
      dfs(next, curr);
      euler_tour.push_back(curr);
      k++;
    }
    end[curr] = k;
  }
};

int root = 0;
int parent[MAX_LOG_V][MAX_V];
int depth[MAX_V];

void dfs2(int v, int p, int d) {
  parent[0][v] = p;
  depth[v] = d;
  for (int i = 0; i < G[v].size(); i++) {
    if (G[v][i] != p)
      dfs2(G[v][i], v, d + 1);
  }
}

void init(int V) {
  memset(depth, 0, sizeof(depth));
  for (int i = 0; i < MAX_LOG_V; i++) {
    for (int j = 0; j < MAX_V; j++) {
      parent[i][j] = 0;
    }
  }
  dfs2(root, -1, 0);
  for (int k = 0; k + 1 < MAX_LOG_V; k++) {
    for (int v = 0; v < V; v++) {
      if (parent[k][v] < 0)
        parent[k + 1][v] = -1;
      else
        parent[k + 1][v] = parent[k][parent[k][v]];
    }
  }
}

int lca(int u, int v) {
  if (depth[u] > depth[v])
    swap(u, v);
  for (int k = 0; k < MAX_LOG_V; k++) {
    if ((depth[v] - depth[u]) >> k & 1) {
      v = parent[k][v];
    }
  }
  if (u == v)
    return u;
  for (int k = MAX_LOG_V - 1; k >= 0; k--) {
    if (parent[k][u] != parent[k][v]) {
      u = parent[k][u];
      v = parent[k][v];
    }
  }
  return parent[0][u];
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  while (1) {
    cin >> n >> q;
    if (n + q == 0)
      break;
    rep(i, 0, n) G[i].clear();
    rep(i, 1, n) {
      int v;
      cin >> v;
      v--;
      G[v].push_back(i);
      G[i].push_back(v);
    }
    vector<bool> marked(n);
    Euler_Tour et(n);
    et.dfs(0, -1);
    init(n);
    BIT bt(2 * n);
    // mark 0
    marked[0] = true;
    bt.add(et.begin[0], 1);
    bt.add(et.end[0] - 1, -1);
    int ans = 0;
    rep(i, 0, q) {
      char c;
      int v;
      cin >> c >> v;
      v--;
      if (c == 'M') {
        marked[v] = true;
        bt.add(et.begin[v], 1);
        bt.add(et.end[v] - 1, -1);
      } else {
        int tmp = 0;
        // check v is marked
        if (marked[v]) {
          tmp = v;
        } else {
          int nowv = v;
          for (int k = MAX_LOG_V - 1; k >= 0; k--) {
            int tmpv = parent[k][nowv];
            if (tmpv == -1)
              tmpv = 0;
            int val = bt.query(et.begin[tmpv], et.begin[v]);
            if (val <= 0) {
              nowv = tmpv;
            }
          }
          tmp = parent[0][nowv];
          if (tmp < 0)
            tmp = 0;
        }
        ans += (tmp + 1);
      }
    }
    cout << ans << endl;
  }
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i < n; i++)
#define int long long
using namespace std;
const int INF = 1e9;
typedef pair<int, int> P;
const int MAX_V = 100010;
const int MAX_LOG_V = 30;

struct BIT {
  int N;
  vector<int> dat;
  BIT() {}
  BIT(int n) {
    N = n;
    dat.resize(N + 1);
  }
  // update k th element (0-index)
  void add(int k, int x) {
    k++;
    while (k <= N) {
      dat[k] += x;
      k += k & -k;
    }
  }
  // sum [0, k) (0-index)
  int sum(int k) {
    int s = 0;
    while (k > 0) {
      s += dat[k];
      k -= k & -k;
    }
    return s;
  }
  // sum [a, b) (0-index)
  int query(int a, int b) { return sum(b) - sum(a); }
};

int n, q;
vector<int> G[MAX_V];

class Euler_Tour {
public:
  // vector<vector<int> > g;
  // begin[v],end[v]はそれぞれvがオイラーツアー上で最初と最後に現れるインデックス
  //[begin[v], end[v])がvを根とする部分木 (半開区間に注意)
  vector<int> euler_tour, begin, end, dist;
  Euler_Tour(int n) : /*g(n),*/ begin(2 * n), end(2 * n){};
  int k = 0, root = 0;
  void dfs(int curr, int par) {
    begin[curr] = k;
    euler_tour.push_back(curr);
    k++;
    for (auto next : G[curr]) {
      if (next == par)
        continue;
      dfs(next, curr);
      euler_tour.push_back(curr);
      k++;
    }
    end[curr] = k;
  }
};

int root = 0;
int parent[MAX_LOG_V][MAX_V];
int depth[MAX_V];

void dfs(int v, int p, int d) {
  parent[0][v] = p;
  depth[v] = d;
  for (int i = 0; i < G[v].size(); i++) {
    if (G[v][i] != p)
      dfs(G[v][i], v, d + 1);
  }
}

void init(int V) {
  dfs(root, -1, 0);
  for (int k = 0; k + 1 < MAX_LOG_V; k++) {
    for (int v = 0; v < V; v++) {
      if (parent[k][v] < 0)
        parent[k + 1][v] = -1;
      else
        parent[k + 1][v] = parent[k][parent[k][v]];
    }
  }
}

int lca(int u, int v) {
  if (depth[u] > depth[v])
    swap(u, v);
  for (int k = 0; k < MAX_LOG_V; k++) {
    if ((depth[v] - depth[u]) >> k & 1) {
      v = parent[k][v];
    }
  }
  if (u == v)
    return u;
  for (int k = MAX_LOG_V - 1; k >= 0; k--) {
    if (parent[k][u] != parent[k][v]) {
      u = parent[k][u];
      v = parent[k][v];
    }
  }
  return parent[0][u];
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  while (1) {
    cin >> n >> q;
    if (n + q == 0)
      break;
    rep(i, 0, n) G[i].clear();
    rep(i, 1, n) {
      int v;
      cin >> v;
      v--;
      G[v].push_back(i);
      G[i].push_back(v);
    }
    Euler_Tour et(n);
    et.dfs(0, -1);
    init(n);
    BIT bt(2 * n);
    // mark 0
    bt.add(et.begin[0], 1);
    bt.add(et.end[0] - 1, -1);

    int ans = 0;
    rep(i, 0, q) {
      char c;
      int v;
      cin >> c >> v;
      v--;
      if (c == 'M') {
        bt.add(et.begin[v], 1);
        bt.add(et.end[v] - 1, -1);
      } else {
        int nowv = v;
        for (int k = MAX_LOG_V - 1; k >= 0; k--) {
          int tmpv = parent[k][nowv];
          int val = bt.query(et.begin[tmpv], et.begin[v]);
          if (val == 0) {
            nowv = tmpv;
          }
        }
        int tmp = parent[0][nowv];
        // cout << tmp << endl;
        ans += (tmp + 1);
      }
    }
    cout << ans << endl;
  }
}