Problem p02373 (C++)

Buggy submission (status: Runtime Error):
#include <cassert>
#include <cmath>
#include <cstdio>
#include <stack>
#include <vector>
#define repeat(i, n) for (int i = 0; (i) < int(n); ++(i))
#define repeat_reverse(i, n) for (int i = (n)-1; (i) >= 0; --(i))
using namespace std;

/**
 * @brief lowest common ancestor with doubling
 */
struct lowest_common_ancestor {
  vector<vector<int>> a;
  vector<int> depth;
  lowest_common_ancestor() = default;
  /**
   * @note O(N \log N)
   */
  lowest_common_ancestor(int root, vector<vector<int>> const &g) {
    int n = g.size();
    int log_n = floor(log2(n));
    a.resize(log_n, vector<int>(n, -1));
    depth.resize(n, -1);
    {
      auto &parent = a[0];
      stack<int> stk;
      depth[root] = 0;
      parent[root] = -1;
      stk.push(root);
      while (not stk.empty()) {
        int x = stk.top();
        stk.pop();
        for (int y : g[x])
          if (depth[y] == -1) {
            depth[y] = depth[x] + 1;
            parent[y] = x;
            stk.push(y);
          }
      }
    }
    repeat(k, log_n - 1) {
      repeat(i, n) {
        if (a[k][i] != -1) {
          a[k + 1][i] = a[k][a[k][i]];
        }
      }
    }
  }
  /**
   * @brief find the LCA of x and y
   * @note O(log N)
   */
  int operator()(int x, int y) const {
    int log_n = a.size();
    if (depth[x] < depth[y])
      swap(x, y);
    repeat_reverse(k, log_n) {
      if (a[k][x] != -1 and depth[a[k][x]] >= depth[y]) {
        x = a[k][x];
      }
    }
    assert(depth[x] == depth[y]);
    assert(x != -1);
    if (x == y)
      return x;
    repeat_reverse(k, log_n) {
      if (a[k][x] != a[k][y]) {
        x = a[k][x];
        y = a[k][y];
      }
    }
    assert(x != y);
    assert(a[0][x] == a[0][y]);
    return a[0][x];
  }
  /**
   * @brief find the descendant of x for y
   */
  int descendant(int x, int y) const {
    assert(depth[x] < depth[y]);
    int log_n = a.size();
    repeat_reverse(k, log_n) {
      if (a[k][y] != -1 and depth[a[k][y]] >= depth[x] + 1) {
        y = a[k][y];
      }
    }
    assert(a[0][y] == x);
    return y;
  }
};

int main() {
  int n;
  scanf("%d", &n);
  vector<vector<int>> g(n);
  repeat(i, n) {
    int edges;
    scanf("%d", &edges);
    while (edges--) {
      int j;
      scanf("%d", &j);
      g[i].push_back(j);
      g[j].push_back(i);
    }
  }
  constexpr int root = 0;
  lowest_common_ancestor lca(root, g);
  int query;
  scanf("%d", &query);
  while (query--) {
    int x, y;
    scanf("%d%d", &x, &y);
    printf("%d\n", lca(x, y));
  }
  return 0;
}

Fixed submission:
#include <cassert>
#include <cmath>
#include <cstdio>
#include <stack>
#include <vector>
#define repeat(i, n) for (int i = 0; (i) < int(n); ++(i))
#define repeat_reverse(i, n) for (int i = (n)-1; (i) >= 0; --(i))
using namespace std;

/**
 * @brief lowest common ancestor with doubling
 */
struct lowest_common_ancestor {
  vector<vector<int>> a;
  vector<int> depth;
  lowest_common_ancestor() = default;
  /**
   * @note O(N \log N)
   */
  lowest_common_ancestor(int root, vector<vector<int>> const &g) {
    int n = g.size();
    int log_n = 1 + floor(log2(n));
    a.resize(log_n, vector<int>(n, -1));
    depth.resize(n, -1);
    {
      auto &parent = a[0];
      stack<int> stk;
      depth[root] = 0;
      parent[root] = -1;
      stk.push(root);
      while (not stk.empty()) {
        int x = stk.top();
        stk.pop();
        for (int y : g[x])
          if (depth[y] == -1) {
            depth[y] = depth[x] + 1;
            parent[y] = x;
            stk.push(y);
          }
      }
    }
    repeat(k, log_n - 1) {
      repeat(i, n) {
        if (a[k][i] != -1) {
          a[k + 1][i] = a[k][a[k][i]];
        }
      }
    }
  }
  /**
   * @brief find the LCA of x and y
   * @note O(log N)
   */
  int operator()(int x, int y) const {
    int log_n = a.size();
    if (depth[x] < depth[y])
      swap(x, y);
    repeat_reverse(k, log_n) {
      if (a[k][x] != -1 and depth[a[k][x]] >= depth[y]) {
        x = a[k][x];
      }
    }
    assert(depth[x] == depth[y]);
    assert(x != -1);
    if (x == y)
      return x;
    repeat_reverse(k, log_n) {
      if (a[k][x] != a[k][y]) {
        x = a[k][x];
        y = a[k][y];
      }
    }
    assert(x != y);
    assert(a[0][x] == a[0][y]);
    return a[0][x];
  }
  /**
   * @brief find the descendant of x for y
   */
  int descendant(int x, int y) const {
    assert(depth[x] < depth[y]);
    int log_n = a.size();
    repeat_reverse(k, log_n) {
      if (a[k][y] != -1 and depth[a[k][y]] >= depth[x] + 1) {
        y = a[k][y];
      }
    }
    assert(a[0][y] == x);
    return y;
  }
};

int main() {
  int n;
  scanf("%d", &n);
  vector<vector<int>> g(n);
  repeat(i, n) {
    int edges;
    scanf("%d", &edges);
    while (edges--) {
      int j;
      scanf("%d", &j);
      g[i].push_back(j);
      g[j].push_back(i);
    }
  }
  constexpr int root = 0;
  lowest_common_ancestor lca(root, g);
  int query;
  scanf("%d", &query);
  while (query--) {
    int x, y;
    scanf("%d%d", &x, &y);
    printf("%d\n", lca(x, y));
  }
  return 0;
}