Problem p02373 (C++)

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

using Graph = vector<vector<int>>;
class LCA {
  int n;
  vector<int> dep;
  vector<vector<int>> par;
  Graph g;
  const int LOGN_MAX = 100;
  void setDep(int v, int d, Graph &tree) {
    dep[v] = d;
    for (int i = 0; i < tree[v].size(); i++)
      setDep(tree[v][i], d + 1, tree);
  }

public:
  LCA(Graph &tree) : n(tree.size()) {
    dep = vector<int>(n);
    par = vector<vector<int>>(min(LOGN_MAX, int(log(n)) + 1), vector<int>(n));
    g = Graph(n);
    for (int i = 0; i < tree.size(); i++) {
      for (int j = 0; j < tree[i].size(); j++) {
        g[tree[i][j]].push_back(i);
      }
    }

    bool isTree = true;
    int root = -1;
    for (int i = 0; i < g.size(); i++) {
      if (g[i].size()) {
        isTree &= (g[i].size() == 1);
      } else if (root == -1) {
        root = i;
        if (g[i].size() == 0) {
          setDep(i, 0, tree);
        }
      } else {
        isTree = false;
      }
    }
    assert(isTree);

    for (int i = 0; i < n; i++) {
      par[0][i] = (g[i].size() ? g[i][0] : i);
    }
    for (int i = 0; i + 1 < par.size(); i++) {
      for (int j = 0; j < par[i].size(); j++) {
        par[i + 1][j] = par[i][par[i][j]];
      }
    }
  }

  int lca(int a, int b) {
    if (dep[a] > dep[b])
      swap(a, b);
    int dist = dep[b] - dep[a];
    for (int i = 0; dist; i++, dist /= 2) {
      if (dist % 2)
        b = par[i][b];
    }
    assert(dep[a] == dep[b]);
    while (true) {
      if (a == b)
        return a;
      if (par[0][a] == par[0][b])
        return par[0][a];
      int lb = 0;
      int ub = par.size();
      //[ub,LOGN_MAX)->same anc
      while (ub - lb > 1) {
        int mid = (lb + ub) / 2;
        if (par[mid][a] == par[mid][b])
          ub = mid;
        else
          lb = mid;
      }
      a = par[lb][a];
      b = par[lb][b];
    }
  }
};

int main() {
  int n;
  cin >> n;
  Graph g(n);
  for (int i = 0; i < n; i++) {
    int k;
    cin >> k;
    for (int j = 0; j < k; j++) {
      int c;
      cin >> c;
      g[i].push_back(c);
    }
  }
  LCA lg(g);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int u, v;
    cin >> u >> v;
    cout << lg.lca(u, v) << endl;
  }
}

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

using Graph = vector<vector<int>>;
class LCA {
  int n;
  vector<int> dep;
  vector<vector<int>> par;
  Graph g;
  const int LOGN_MAX = 100;
  void setDep(int v, int d, Graph &tree) {
    dep[v] = d;
    for (int i = 0; i < tree[v].size(); i++)
      setDep(tree[v][i], d + 1, tree);
  }

public:
  LCA(Graph &tree) : n(tree.size()) {
    dep = vector<int>(n);
    par = vector<vector<int>>(min(LOGN_MAX, int(log2(n)) + 1), vector<int>(n));
    g = Graph(n);
    for (int i = 0; i < tree.size(); i++) {
      for (int j = 0; j < tree[i].size(); j++) {
        g[tree[i][j]].push_back(i);
      }
    }

    bool isTree = true;
    int root = -1;
    for (int i = 0; i < g.size(); i++) {
      if (g[i].size()) {
        isTree &= (g[i].size() == 1);
      } else if (root == -1) {
        root = i;
        if (g[i].size() == 0) {
          setDep(i, 0, tree);
        }
      } else {
        isTree = false;
      }
    }
    assert(isTree);

    for (int i = 0; i < n; i++) {
      par[0][i] = (g[i].size() ? g[i][0] : i);
    }
    for (int i = 0; i + 1 < par.size(); i++) {
      for (int j = 0; j < par[i].size(); j++) {
        par[i + 1][j] = par[i][par[i][j]];
      }
    }
  }

  int lca(int a, int b) {
    if (dep[a] > dep[b])
      swap(a, b);
    int dist = dep[b] - dep[a];
    for (int i = 0; dist; i++, dist /= 2) {
      if (dist % 2)
        b = par[i][b];
    }
    assert(dep[a] == dep[b]);
    while (true) {
      if (a == b)
        return a;
      if (par[0][a] == par[0][b])
        return par[0][a];
      int lb = 0;
      int ub = par.size();
      //[ub,LOGN_MAX)->same anc
      while (ub - lb > 1) {
        int mid = (lb + ub) / 2;
        if (par[mid][a] == par[mid][b])
          ub = mid;
        else
          lb = mid;
      }
      a = par[lb][a];
      b = par[lb][b];
    }
  }
};

int main() {
  int n;
  cin >> n;
  Graph g(n);
  for (int i = 0; i < n; i++) {
    int k;
    cin >> k;
    for (int j = 0; j < k; j++) {
      int c;
      cin >> c;
      g[i].push_back(c);
    }
  }
  LCA lg(g);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int u, v;
    cin >> u >> v;
    cout << lg.lca(u, v) << endl;
  }
}