Problem p02373 (C++) — buggy submission, verdict: Memory Limit Exceeded

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

struct LowestCommonAncestor {
  LowestCommonAncestor(size_t size)
      : size(size), MaxlgV(32 - __builtin_clz(size - 1)), G(size), dep(size),
        par(MaxlgV, vector<int>(size)) {}

  size_t size, MaxlgV;
  int root;
  vector<vector<int>> G, par;
  vector<int> dep;

  void add_edge(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
  }

  void dfs(int v, int u, int d) {
    dep[v] = d;
    par[0][v] = u;
    for (int e : G[v])
      if (e != u)
        dfs(e, v, d + 1);
  }

  void build(int r) {
    dfs(root = r, -1, 0);
    for (int k = 0; k + 1 < MaxlgV; k++) {
      for (int v = 0; v < size; v++) {
        if (par[k][v] < 0)
          par[k + 1][v] = -1;
        else
          par[k + 1][v] = par[k][par[k][v]];
      }
    }
  }

  int lca(int u, int v) {
    if (dep[u] > dep[v])
      swap(u, v);
    for (int k = 0; k < MaxlgV; k++) {
      if ((dep[v] - dep[u]) >> k & 1) {
        v = par[k][v];
      }
    }

    if (u == v)
      return u;

    for (int k = MaxlgV - 1; k >= 0; k--) {
      if (par[k][u] != par[k][v]) {
        u = par[k][u];
        v = par[k][v];
      }
    }

    return par[0][u];
  }

  int dist(int u, int v) {
    int z = lca(u, v);
    return dep[u] + dep[v] - 2 * dep[z];
  }
};

// https://onlinejudge.u-aizu.ac.jp/#/courses/library/5/GRL/5/GRL_5_C
int main() {
  int N;
  cin >> N;

  LowestCommonAncestor tree(N);
  for (int i = 0; i < N; ++i) {
    int k;
    cin >> k;
    while (k--) {
      int c;
      cin >> c;

      tree.add_edge(i, c);
    }
  }

  tree.build(0);

  int q;
  cin >> q;

  while (q--) {
    int u, v;
    cin >> u >> v;

    cout << tree.lca(u, v) << endl;
  }
}


Error: MLE

Fixed submission:

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

struct LowestCommonAncestor {
  LowestCommonAncestor(size_t size)
      : size(size), MaxlgV(1 << (32 - __builtin_clz(size - 1))), G(size),
        dep(size), par(MaxlgV, vector<int>(size)) {}

  size_t size, MaxlgV;
  int root;
  vector<vector<int>> G, par;
  vector<int> dep;

  void add_edge(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
  }

  void dfs(int v, int u, int d) {
    dep[v] = d;
    par[0][v] = u;
    for (int e : G[v])
      if (e != u)
        dfs(e, v, d + 1);
  }

  void build(int r) {
    dfs(root = r, -1, 0);
    for (int k = 0; k + 1 < MaxlgV; k++) {
      for (int v = 0; v < size; v++) {
        if (par[k][v] < 0)
          par[k + 1][v] = -1;
        else
          par[k + 1][v] = par[k][par[k][v]];
      }
    }
  }

  int lca(int u, int v) {
    if (dep[u] > dep[v])
      swap(u, v);
    for (int k = 0; k < MaxlgV; k++) {
      if ((dep[v] - dep[u]) >> k & 1) {
        v = par[k][v];
      }
    }

    if (u == v)
      return u;

    for (int k = MaxlgV - 1; k >= 0; k--) {
      if (par[k][u] != par[k][v]) {
        u = par[k][u];
        v = par[k][v];
      }
    }

    return par[0][u];
  }

  int dist(int u, int v) {
    int z = lca(u, v);
    return dep[u] + dep[v] - 2 * dep[z];
  }
};

// https://onlinejudge.u-aizu.ac.jp/#/courses/library/5/GRL/5/GRL_5_C
int main() {
  int N;
  cin >> N;

  LowestCommonAncestor tree(N);
  for (int i = 0; i < N; ++i) {
    int k;
    cin >> k;
    while (k--) {
      int c;
      cin >> c;

      tree.add_edge(i, c);
    }
  }

  tree.build(0);

  int q;
  cin >> q;

  while (q--) {
    int u, v;
    cin >> u >> v;

    cout << tree.lca(u, v) << endl;
  }
}