Problem p02986 (C++)

Buggy submission (status: Runtime Error):
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
/////////////////////////////////////////////////////////////////////////
// LCA
/////////////////////////////////////////////////////////////////////////
class LowestCommonAncestor {
public:
  LowestCommonAncestor();
  LowestCommonAncestor(const vector<vector<int>> &g, int r);
  LowestCommonAncestor(const vector<int> g[], int r, int siz);
  void build(const vector<vector<int>> &g, int r);
  void build(const vector<int> g[], int r, int siz);
  int get(int u, int v) const;
  int getParent(int cur, int u) const;
  int getDepth(int cur) const;

private:
  void initialize();
  void dfs(int cur, int par, int d);
  static constexpr int MAX_SIZE = 30;
  vector<vector<int>> graph;
  vector<vector<int>> parent;
  vector<int> depth;
  int bit_;
  int root;
};

LowestCommonAncestor::LowestCommonAncestor(){};
LowestCommonAncestor::LowestCommonAncestor(const vector<vector<int>> &g,
                                           int r = -1)
    : graph(g), root(r) {
  if (root == -1)
    root = 0;
  initialize();
}
LowestCommonAncestor::LowestCommonAncestor(const vector<int> g[], int r = -1,
                                           int siz = -1)
    : root(r) {
  assert(siz > 0);
  if (root == -1)
    root = 0;
  graph.resize(siz);
  for (int i = 0; i < siz; i++)
    for (auto &j : g[i])
      graph[i].push_back(j);
  initialize();
}
void LowestCommonAncestor::build(const vector<vector<int>> &g, int r = -1) {
  root = r;
  graph = g;
  if (root == -1)
    root = 0;
  initialize();
}
void LowestCommonAncestor::build(const vector<int> g[], int r = -1,
                                 int siz = -1) {
  assert(siz > 0);
  root = r;
  graph.resize(siz);
  for (int i = 0; i < siz; i++)
    for (auto &j : g[i])
      graph[i].push_back(j);
  initialize();
}
int LowestCommonAncestor::get(int u, int v) const {
  assert(u >= 0 && u < (int)graph.size());
  assert(v >= 0 && v < (int)graph.size());
  if (depth[u] > depth[v])
    swap(u, v);
  for (int i = 0; i < bit_; ++i)
    if (((depth[v] - depth[u]) >> i) & i)
      v = parent[v][i];
  if (u == v)
    return u;
  for (int i = bit_ - 1; i >= 0; --i)
    if (parent[u][i] != parent[v][i])
      u = parent[u][i], v = parent[v][i];
  return parent[u][0];
}
int LowestCommonAncestor::getParent(int cur, int u = 0) const {
  assert(cur >= 0 && cur < (int)graph.size());
  assert(u >= 0 && (int)graph[cur].size() > u);
  return parent[cur][u];
}
int LowestCommonAncestor::getDepth(int cur) const {
  assert(cur >= 0 && cur < (int)depth.size());
  return depth[cur];
}
void LowestCommonAncestor::initialize() {
  bit_ = 1;
  while ((1 << bit_) < (int)graph.size())
    ++bit_;
  parent = vector<vector<int>>((int)graph.size(), vector<int>(bit_));
  depth.assign((int)graph.size(), -1);
  dfs(root, -1, 0);
  for (int i = 0; i < bit_ - 1; ++i) {
    for (int v = 0; v < (int)graph.size(); ++v) {
      if (depth[v] == -1)
        continue;
      if (parent[v][i] < 0)
        parent[v][i + 1] = -1;
      else
        parent[v][i + 1] = parent[parent[v][i]][i];
    }
  }
}
void LowestCommonAncestor::dfs(int cur, int par, int d) {
  parent[cur][0] = par;
  depth[cur] = d;
  for (auto &child : graph[cur])
    if (child != par)
      dfs(child, cur, d + 1);
}
using LCA = LowestCommonAncestor;
/////////////////////////////////////////////////////////////////////////
// END LCA
/////////////////////////////////////////////////////////////////////////
int n;
vector<vector<int>> g1[101010];
vector<int> g2[101010];
vector<int> need[101010];
map<int, int> res_cnt[101010], res_sum[101010];
int dist[101010];
int col_cnt[101010], col_sum[101010];
void dfs(int cur, int par) {
  for (int c : need[cur]) {
    res_cnt[cur][c] = col_cnt[c];
    res_sum[cur][c] = col_sum[c];
  }
  for (auto nxt : g1[cur]) {
    int child = nxt[0];
    int c = nxt[1];
    int d = nxt[2];
    if (child == par)
      continue;
    dist[child] = dist[cur] + d;
    col_cnt[c]++;
    col_sum[c] += d;
    dfs(child, cur);
    col_cnt[c]--;
    col_sum[c] -= d;
  }
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int q;
  cin >> n >> q;
  for (int i = 0; i + 1 < n; i++) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    a--;
    b--;
    c--;
    g1[a].push_back({b, c, d});
    g1[b].push_back({a, c, d});
    g2[a].push_back(b);
    g2[b].push_back(a);
  }
  LCA lca(g2, 0, 101010);
  vector<int> inx(q), iny(q), inu(q), inv(q), inw(q);
  for (int i = 0; i < q; i++) {
    cin >> inx[i] >> iny[i] >> inu[i] >> inv[i];
    inx[i]--;
    inu[i]--;
    inv[i]--;
    inw[i] = lca.get(inu[i], inv[i]);
    need[inu[i]].push_back(inx[i]);
    need[inv[i]].push_back(inx[i]);
    need[inw[i]].push_back(inx[i]);
  }
  dfs(0, -1);
  for (int i = 0; i < q; i++) {
    int du = dist[inu[i]] - res_sum[inu[i]][inx[i]] +
             res_cnt[inu[i]][inx[i]] * iny[i];
    int dv = dist[inv[i]] - res_sum[inv[i]][inx[i]] +
             res_cnt[inv[i]][inx[i]] * iny[i];
    int dw = dist[inw[i]] - res_sum[inw[i]][inx[i]] +
             res_cnt[inw[i]][inx[i]] * iny[i];
    cout << du + dv - 2 * dw << '\n';
  }
  return 0;
}


Fixed submission:
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
/////////////////////////////////////////////////////////////////////////
// LCA
/////////////////////////////////////////////////////////////////////////
class LowestCommonAncestor {
public:
  LowestCommonAncestor();
  LowestCommonAncestor(const vector<vector<int>> &g, int r);
  LowestCommonAncestor(const vector<int> g[], int r, int siz);
  void build(const vector<vector<int>> &g, int r);
  void build(const vector<int> g[], int r, int siz);
  int get(int u, int v) const;
  int getParent(int cur, int u) const;
  int getDepth(int cur) const;

private:
  void initialize();
  void dfs(int cur, int par, int d);
  static constexpr int MAX_SIZE = 30;
  vector<vector<int>> graph;
  vector<vector<int>> parent;
  vector<int> depth;
  int bit_;
  int root;
};

LowestCommonAncestor::LowestCommonAncestor(){};
LowestCommonAncestor::LowestCommonAncestor(const vector<vector<int>> &g,
                                           int r = -1)
    : graph(g), root(r) {
  if (root == -1)
    root = 0;
  initialize();
}
LowestCommonAncestor::LowestCommonAncestor(const vector<int> g[], int r = -1,
                                           int siz = -1)
    : root(r) {
  assert(siz > 0);
  if (root == -1)
    root = 0;
  graph.resize(siz);
  for (int i = 0; i < siz; i++)
    for (auto &j : g[i])
      graph[i].push_back(j);
  initialize();
}
void LowestCommonAncestor::build(const vector<vector<int>> &g, int r = -1) {
  root = r;
  graph = g;
  if (root == -1)
    root = 0;
  initialize();
}
void LowestCommonAncestor::build(const vector<int> g[], int r = -1,
                                 int siz = -1) {
  assert(siz > 0);
  root = r;
  graph.resize(siz);
  for (int i = 0; i < siz; i++)
    for (auto &j : g[i])
      graph[i].push_back(j);
  initialize();
}
int LowestCommonAncestor::get(int u, int v) const {
  assert(u >= 0 && u < (int)graph.size());
  assert(v >= 0 && v < (int)graph.size());
  if (depth[u] > depth[v])
    swap(u, v);
  for (int i = 0; i < bit_; ++i)
    if (((depth[v] - depth[u]) >> i) & 1)
      v = parent[v][i];
  if (u == v)
    return u;
  for (int i = bit_ - 1; i >= 0; --i)
    if (parent[u][i] != parent[v][i])
      u = parent[u][i], v = parent[v][i];
  return parent[u][0];
}
int LowestCommonAncestor::getParent(int cur, int u = 0) const {
  assert(cur >= 0 && cur < (int)graph.size());
  assert(u >= 0 && (int)graph[cur].size() > u);
  return parent[cur][u];
}
int LowestCommonAncestor::getDepth(int cur) const {
  assert(cur >= 0 && cur < (int)depth.size());
  return depth[cur];
}
void LowestCommonAncestor::initialize() {
  bit_ = 1;
  while ((1 << bit_) < (int)graph.size())
    ++bit_;
  parent = vector<vector<int>>((int)graph.size(), vector<int>(bit_));
  depth.assign((int)graph.size(), -1);
  dfs(root, -1, 0);
  for (int i = 0; i < bit_ - 1; ++i) {
    for (int v = 0; v < (int)graph.size(); ++v) {
      if (depth[v] == -1)
        continue;
      if (parent[v][i] < 0)
        parent[v][i + 1] = -1;
      else
        parent[v][i + 1] = parent[parent[v][i]][i];
    }
  }
}
void LowestCommonAncestor::dfs(int cur, int par, int d) {
  parent[cur][0] = par;
  depth[cur] = d;
  for (auto &child : graph[cur])
    if (child != par)
      dfs(child, cur, d + 1);
}
using LCA = LowestCommonAncestor;
/////////////////////////////////////////////////////////////////////////
// END LCA
/////////////////////////////////////////////////////////////////////////
int n;
vector<vector<int>> g1[101010];
vector<int> g2[101010];
vector<int> need[101010];
map<int, int> res_cnt[101010], res_sum[101010];
int dist[101010];
int col_cnt[101010], col_sum[101010];
void dfs(int cur, int par) {
  for (int c : need[cur]) {
    res_cnt[cur][c] = col_cnt[c];
    res_sum[cur][c] = col_sum[c];
  }
  for (auto nxt : g1[cur]) {
    int child = nxt[0];
    int c = nxt[1];
    int d = nxt[2];
    if (child == par)
      continue;
    dist[child] = dist[cur] + d;
    col_cnt[c]++;
    col_sum[c] += d;
    dfs(child, cur);
    col_cnt[c]--;
    col_sum[c] -= d;
  }
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int q;
  cin >> n >> q;
  for (int i = 0; i + 1 < n; i++) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    a--;
    b--;
    c--;
    g1[a].push_back({b, c, d});
    g1[b].push_back({a, c, d});
    g2[a].push_back(b);
    g2[b].push_back(a);
  }
  LCA lca(g2, 0, 101010);
  vector<int> inx(q), iny(q), inu(q), inv(q), inw(q);
  for (int i = 0; i < q; i++) {
    cin >> inx[i] >> iny[i] >> inu[i] >> inv[i];
    inx[i]--;
    inu[i]--;
    inv[i]--;
    inw[i] = lca.get(inu[i], inv[i]);
    need[inu[i]].push_back(inx[i]);
    need[inv[i]].push_back(inx[i]);
    need[inw[i]].push_back(inx[i]);
  }
  dfs(0, -1);
  for (int i = 0; i < q; i++) {
    int du = dist[inu[i]] - res_sum[inu[i]][inx[i]] +
             res_cnt[inu[i]][inx[i]] * iny[i];
    int dv = dist[inv[i]] - res_sum[inv[i]][inx[i]] +
             res_cnt[inv[i]][inx[i]] * iny[i];
    int dw = dist[inw[i]] - res_sum[inw[i]][inx[i]] +
             res_cnt[inw[i]][inx[i]] * iny[i];
    cout << du + dv - 2 * dw << '\n';
  }
  return 0;
}