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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

// c++11
#include <array>
#include <tuple>
#include <unordered_map>
#include <unordered_set>

#define mp make_pair
#define mt make_tuple
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;

const int INF = 1 << 29;
const ll LL_INF = 1LL << 60;
const double EPS = 1e-9;
const ll MOD = 1000000007;

const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
int N, M;
int Q;
const int MAX_N = 100010;
vector<vector<int>> edges;
// LowestCommonAncestor
// init -> lca(a, b)
template <typename T> class LowestCommonAncestor {
public:
  static const int MAX_LOG_V = 30;
  static const int NONE_NODE = -1;
  vector<int>
      parents[MAX_LOG_V]; // follow parents 2^k times node index (ex
                          // parents[k][v] start v follow parents 2^k times)
  vector<int> depths;     // the depth from root.
  T edges;
  void dfs(int pos, int pre, int depth = 0) {
    parents[0][pos] = pre;
    depths[pos] = depth;
    for (const auto &nxt : edges[pos]) {
      if (nxt != pre) {
        dfs(nxt, pos, depth + 1);
      }
    }
  }

  void init(int root_idx, int V, const T &edges) {
    this->depths.resize(V);
    this->edges = edges;
    for (int i = 0; i < MAX_LOG_V; i++) {
      parents[i].resize(V);
    }
    dfs(root_idx, NONE_NODE, 0);
    for (int k = 0; k + 1 < MAX_LOG_V; k++) {
      for (int v = 0; v < V; v++) {
        if (parents[k][v] == NONE_NODE) {
          parents[k + 1][v] = NONE_NODE;
        } else {
          parents[k + 1][v] = parents[k][parents[k][v]];
        }
      }
    }
  }
  // O(logN)
  int lca(int u, int v) {

    if (depths[u] > depths[v]) {
      swap(u, v);
    }

    // follow parents by same level.
    for (int k = 0; k < MAX_LOG_V; k++) {
      int diff = depths[v] - depths[u];
      if ((diff >> k) & 1) {
        v = parents[k][v];
        // cerr << "depth = " << depths[v] << endl;
      }
    }
    if (u == v) {
      return u;
    }

    // binary search to find lcm(u, v)
    for (int k = MAX_LOG_V - 1; k >= 0; k--) {
      if (parents[k][u] != parents[k][v]) {
        u = parents[k][u];
        v = parents[k][v];
      }
    }
    return parents[0][v];
  }
};
int main() {
  edges.resize(MAX_N);
  cin >> N;

  for (int i = 0; i < N; i++) {
    int K;
    cin >> K;
    for (int k = 0; k < K; k++) {
      int c;
      cin >> c;
      edges[i].push_back(c);
      edges[c].push_back(i);
    }
  }

  LowestCommonAncestor<vector<vector<int>>> lca;
  lca.init(0, N, edges);
  cin >> Q;
  for (int i = 0; i < Q; i++) {
    int u, v;
    cin >> u >> v;
    int res = lca.lca(u, v);
    cout << res << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define repi(i, a, b) for (int i = (a); i < (b); i++)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

const int INF = 1 << 29;
const double EPS = 1e-9;

const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
int n;
vector<int> G[100010];
int parent[100010]; // parent[i]はiの親
int depth[100010];  // depth[i]はiの根からの深さ
int root = 0;       // 今回は0が根
void dfs(int v, int p, int d) {
  parent[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() { dfs(root, -1, 0); }

int lca(int u, int v) {
  while (depth[u] > depth[v])
    u = parent[u];
  while (depth[u] < depth[v])
    v = parent[v];
  while (u != v) {
    u = parent[u];
    v = parent[v];
  }
  return u;
}
int main() {
  cin >> 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);
      // G[c].push_back(i);
    }
  }
  init();
  int q;
  cin >> q;

  for (int i = 0; i < q; i++) {
    int u, v;
    cin >> u >> v;
    cout << lca(u, v) << endl;
  }
  return 0;
}