Problem p02373 (C++) — buggy submission, verdict: Runtime Error

// LCA: Doubling

// ???????????????
#include <algorithm>
#include <iostream>
#include <vector>
// ?????????
class RootedTree {
public:
  RootedTree(int n);
  int size() const;
  int parent(int v, int n = 1) const;
  void join(int u, int v);
  void initialize(int root);
  int lca(int u, int v) const;

private:
  void initialize(int current, int previous, int depth);
  std::vector<std::vector<int>> edge_;
  std::vector<std::vector<int>>
      parent_; // parent_[v][i]: ??????v???2^i????????????
  std::vector<int> depth_;

public: // ???????????°??¨
  void print(int c, int p) {
    std::cout << c << ":";
    for (auto i : parent_[c])
      std::cout << " " << i;
    std::cout << std::endl;
    for (auto n : edge_[c])
      if (n != p)
        print(n, c);
  }
};
// ?????????????????????
RootedTree::RootedTree(int n) : edge_(n) {}
// ????????°
int RootedTree::size() const { return edge_.size(); }
// ??????v???n????????????
int RootedTree::parent(int v, int n) const {
  if (!n)
    return v;
  if (__builtin_popcount(n) == 1)
    return parent_[v][__builtin_ctz(n)];
  for (int i = 31 - __builtin_clz(n); 0 <= i; --i)
    if ((n >> i) & 1)
      v = parent_[v][i];
  return v;
}
// ????????????
void RootedTree::join(int u, int v) {
  edge_[u].push_back(v);
  edge_[v].push_back(u);
}
// ?????????
void RootedTree::initialize(int root) {
  parent_.assign(size(), std::vector<int>());
  depth_.assign(size(), 0);
  initialize(root, root, 0);
}
void RootedTree::initialize(int current, int previous, int depth) {
  depth_[current] = depth;
  parent_[current].push_back(previous);
  for (int i = 1; (1 << i) <= depth; ++i)
    parent_[current].push_back(parent_[parent_[current][i - 1]][i - 1]);
  for (const auto &next : edge_[current])
    if (next != previous)
      initialize(next, current, depth + 1);
}
// LCA
int RootedTree::lca(int u, int v) const {
  // u, v???????????±????????????
  if (depth_[u] > depth_[v])
    std::swap(u, v);
  v = parent(v, depth_[v] - depth_[u]);
  // LCA????±???????
  if (u == v)
    return u;
  for (int i = 31 - __builtin_clz(depth_[u]); 0 <= i; --i) {
    if (parent_[u][i] == parent_[v][i])
      continue;
    u = parent_[u][i];
    v = parent_[v][i];
    i = std::min(i, 31 - __builtin_clz(depth_[u]) + 1);
  }
  return parent_[u][0];
}

#include <bits/stdc++.h>
using namespace std;
int main() {
  int n;
  cin >> n;
  RootedTree tree(n);
  for (int i = 0; i < n; ++i) {
    int k;
    cin >> k;
    for (int j = 0; j < k; ++j) {
      int c;
      cin >> c;
      tree.join(i, c);
    }
  }
  tree.initialize(0);
  int q;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    int u, v;
    cin >> u >> v;
    cout << tree.lca(u, v) << endl;
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
// ?????????
class RootedTree {
public:
  RootedTree(int n);
  int size() const;
  int parent(int v, int n = 1) const;
  void join(int u, int v);
  void initialize(int root);
  int lca(int u, int v) const;

private:
  void initialize(int current, int previous, int depth);
  std::vector<std::vector<int>> edge_;
  std::vector<std::vector<int>>
      parent_; // parent_[v][i]: ??????v???2^i????????????
  std::vector<int> depth_;

public: // ???????????°??¨
  void print(int c, int p) {
    std::cout << c << ":";
    for (auto i : parent_[c])
      std::cout << " " << i;
    std::cout << std::endl;
    for (auto n : edge_[c])
      if (n != p)
        print(n, c);
  }
};
// ?????????????????????
RootedTree::RootedTree(int n) : edge_(n) {}
// ????????°
int RootedTree::size() const { return edge_.size(); }
// ??????v???n????????????
int RootedTree::parent(int v, int n) const {
  if (!n)
    return v;
  if (__builtin_popcount(n) == 1)
    return parent_[v][__builtin_ctz(n)];
  for (int i = 31 - __builtin_clz(n); 0 <= i; --i)
    if ((n >> i) & 1)
      v = parent_[v][i];
  return v;
}
// ????????????
void RootedTree::join(int u, int v) {
  edge_[u].push_back(v);
  edge_[v].push_back(u);
}
// ?????????
void RootedTree::initialize(int root) {
  parent_.assign(size(), std::vector<int>());
  depth_.assign(size(), 0);
  initialize(root, root, 0);
}
void RootedTree::initialize(int current, int previous, int depth) {
  depth_[current] = depth;
  parent_[current].push_back(previous);
  for (int i = 1; (1 << i) <= depth; ++i)
    parent_[current].push_back(parent_[parent_[current][i - 1]][i - 1]);
  for (const auto &next : edge_[current])
    if (next != previous)
      initialize(next, current, depth + 1);
}
// LCA
int RootedTree::lca(int u, int v) const {
  // u, v???????????±????????????
  if (u > v)
    std::swap(u, v);
  v = parent(v, depth_[v] - depth_[u]);
  // LCA????±???????
  if (u == v)
    return u;
  for (int i = 31 - __builtin_clz(depth_[u]); 0 <= i; --i) {
    if (parent_[u][i] == parent_[v][i])
      continue;
    u = parent_[u][i];
    v = parent_[v][i];
    i = std::min(i, 31 - __builtin_clz(depth_[u]));
  }
  return parent_[u][0];
}

#include <bits/stdc++.h>
using namespace std;
int main() {
  int n;
  cin >> n;
  RootedTree tree(n);
  for (int i = 0; i < n; ++i) {
    int k;
    cin >> k;
    for (int j = 0; j < k; ++j) {
      int c;
      cin >> c;
      tree.join(i, c);
    }
  }
  tree.initialize(0);
  int q;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    int u, v;
    cin >> u >> v;
    cout << tree.lca(u, v) << endl;
  }
}