Problem p02373 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;

const int MAXN = 100005;

int path[2 * MAXN], depth[2 * MAXN],
    idx[MAXN]; // idx : the index of node in dfs path

int par[MAXN];
vi adjList[MAXN];

class SparseTable {
private:
  int n, h;
  vvi t;

  int combine(int l, int r) {
    if (l == -1 || r == -1)
      return max(l, r);

    return depth[l] < depth[r] ? l : r;
  }

public:
  SparseTable(int size) {
    n = size;
    h = ceil(log2(n));
    t.assign(h, vi());

    t[0].assign(n, 0);
    for (int i = 0; i < n; i++)
      t[0][i] = i;
    for (int i = 1; i < h; i++) {
      t[i].assign(n, 0);
      for (int j = 0; j + (1 << i) <= n; j++) {
        t[i][j] = combine(t[i - 1][j], t[i - 1][j + (1 << (i - 1))]);
      }
    }
  }
  int query(int l, int r) { // query in range v[l,r]
    int p = 31 - __builtin_clz(r - l + 1);
    return combine(t[p][l], t[p][r - (1 << p) + 1]);
  }
};

int cnt = 0;

// build dfs path, depth
void dfs(int curr, int d) {
  idx[curr] = cnt;
  path[cnt] = curr;
  depth[cnt++] = d;
  for (int i = 0; i < adjList[curr].size(); i++) {
    dfs(adjList[curr][i], d + 1);

    path[cnt] = curr;
    depth[cnt++] = d;
  }
}
int N, M, Q, v;

int main() {

  memset(par, -1, sizeof(par));

  scanf("%d", &N);
  for (int u = 0; u < N; u++) {
    scanf("%d", &M);

    for (int i = 0; i < M; i++) {
      scanf("%d", &v);

      par[v] = u;
      adjList[u].push_back(v);
    }
  }

  int root;
  for (int i = 0; i < N; i++)
    if (par[i] == -1)
      root = i;

  dfs(root, 0);

  SparseTable st(cnt);

  scanf("%d", &Q);
  for (int i = 0; i < Q; i++) {
    int u, v, l, r;
    scanf("%d%d", &u, &v);

    l = idx[u];
    r = idx[v];
    if (l > r)
      swap(l, r);

    int id = st.query(l, r);
    printf("%d\n", path[id]);
  }

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;

const int MAXN = 100005;

int path[2 * MAXN], depth[2 * MAXN],
    idx[MAXN]; // idx : the index of node in dfs path

int par[MAXN];
vi adjList[MAXN];

class SparseTable {
private:
  int n, h;
  vvi t;

  int combine(int l, int r) {
    if (l == -1 || r == -1)
      return max(l, r);

    return depth[l] < depth[r] ? l : r;
  }

public:
  SparseTable(int size) {
    n = size;
    h = (n == 1 ? 1 : ceil(log2(n)));
    t.assign(h, vi());

    t[0].assign(n, 0);
    for (int i = 0; i < n; i++)
      t[0][i] = i;
    for (int i = 1; i < h; i++) {
      t[i].assign(n, 0);
      for (int j = 0; j + (1 << i) <= n; j++) {
        t[i][j] = combine(t[i - 1][j], t[i - 1][j + (1 << (i - 1))]);
      }
    }
  }
  int query(int l, int r) { // query in range v[l,r]
    int p = 31 - __builtin_clz(r - l + 1);
    return combine(t[p][l], t[p][r - (1 << p) + 1]);
  }
};

int cnt = 0;

// build dfs path, depth
void dfs(int curr, int d) {
  idx[curr] = cnt;
  path[cnt] = curr;
  depth[cnt++] = d;
  for (int i = 0; i < adjList[curr].size(); i++) {
    dfs(adjList[curr][i], d + 1);

    path[cnt] = curr;
    depth[cnt++] = d;
  }
}
int N, M, Q, v;

int main() {

  memset(par, -1, sizeof(par));

  scanf("%d", &N);
  for (int u = 0; u < N; u++) {
    scanf("%d", &M);

    for (int i = 0; i < M; i++) {
      scanf("%d", &v);

      par[v] = u;
      adjList[u].push_back(v);
    }
  }

  int root;
  for (int i = 0; i < N; i++)
    if (par[i] == -1)
      root = i;

  dfs(root, 0);

  SparseTable st(cnt);

  scanf("%d", &Q);
  for (int i = 0; i < Q; i++) {
    int u, v, l, r;
    scanf("%d%d", &u, &v);

    l = idx[u];
    r = idx[v];
    if (l > r)
      swap(l, r);

    int id = st.query(l, r);
    printf("%d\n", path[id]);
  }

  return 0;
}