Problem p02986 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using i64 = long long;

struct Edge {
  int to, c, d;
  Edge(int to, int c, int d) : to(to), c(c), d(d) {}
};

constexpr int size = 1 << 17;
i64 dat[size * 2 - 1];

auto query(int a, int b, int k, int l, int r) {
  if (r <= a || b <= l)
    return 0ll;
  if (a <= l && r <= b)
    return dat[k];
  return query(a, b, k * 2 + 1, l, (l + r) / 2) +
         query(a, b, k * 2 + 2, (l + r) / 2, r);
}

void update(int i, i64 x) {
  i += size - 1;
  dat[i] = x;
  while (i) {
    i = (i - 1) / 2;
    dat[i] = dat[i * 2 + 1] + dat[i * 2 + 2];
  }
}

auto dig(int k) {
  if (k >= size - 1)
    return dat[k];
  return dat[k] = dig(k * 2 + 1) + dig(k * 2 + 2);
}

void build(const std::deque<i64> &v) {
  memset(dat, 0, sizeof(dat));
  for (int i = 0; i < v.size(); i++) {
    dat[i + size - 1] = v[i];
  }
  dig(0);
}

std::vector<std::deque<Edge>> g;
std::vector<std::deque<std::pair<int, int>>> ce;
std::deque<i64> euler_tour;
std::vector<int> estart, depth;

int par[100010][17];

void dfs(int v, int p, int c, int j) {
  estart[v] = euler_tour.size() - 1;
  for (auto &e : g[v]) {
    if (e.to == p)
      continue;
    ce[e.c].emplace_back(euler_tour.size(), e.d);
    euler_tour.push_back(e.d);
    depth[e.to] = depth[v] + 1;
    par[e.to][0] = v;
    dfs(e.to, v, e.c, e.d);
  }
  ce[c].emplace_back(euler_tour.size(), -j);
  euler_tour.push_back(-j);
}

int main() {
  int n, q;
  std::cin >> n >> q;
  g.resize(n);
  ce.resize(n);
  estart.resize(n, -1);
  depth.resize(n, -1);
  for (int i = 1; i < n; i++) {
    int u, v, c, d;
    std::cin >> u >> v >> c >> d;
    --u;
    --v;
    g[u].emplace_back(v, c, d);
    g[v].emplace_back(u, c, d);
  }

  for (int i = 0; i < n; i++)
    for (int j = 0; j < 17; j++)
      par[i][j] = -1;
  euler_tour.emplace_back(0);
  dfs(0, -1, 0, 0);
  build(euler_tour);

  for (int i = 0; i + 1 < 17; i++)
    for (int j = 0; j < n; j++) {
      if (par[j][i] < 0)
        continue;
      par[j][i + 1] = par[par[j][i]][i];
    }

  std::vector<std::deque<std::tuple<int, int, int, int>>> cq(n);
  for (int i = 0; i < q; i++) {
    int x, y, u, v;
    std::cin >> x >> y >> u >> v;
    cq[x].emplace_back(y, u - 1, v - 1, i);
  }

  constexpr i64 pp = 10000000000;
  auto sgn = [](auto t) { return t > 0 ? 1 : -1; };

  std::vector<int> ret(q);
  for (int i = 1; i < n; i++) {
    for (auto &che : ce[i]) {
      update(che.first, sgn(che.second) * pp);
    }
    for (auto &qq : cq[i]) {
      auto u = std::get<1>(qq), v = std::get<2>(qq);

      if (depth[u] > depth[v])
        std::swap(u, v);
      auto diff = depth[v] - depth[u];
      for (int i = 16; i >= 0; i--) {
        if (diff & (1 << i))
          v = par[v][i];
      }

      int l = -1, r = n;
      while (r - l > 1) {
        auto k = (l + r) / 2;
        int a = u, b = v;
        bool flg = a == b;
        for (int i = 16; !flg && i >= 0; i--) {
          if ((k & (1 << i)) == 0)
            continue;
          a = par[a][i];
          b = par[b][i];
          if (a == b)
            flg = true;
        }
        if (flg)
          r = k;
        else
          l = k;
      }

      int lca = v;
      for (int i = 16; i >= 0; i--) {
        if (r & (1 << i))
          lca = par[lca][i];
      }

      auto d1 = query(estart[lca] + 1, estart[std::get<1>(qq)] + 1, 0, 0, size),
           d2 = query(estart[lca] + 1, estart[std::get<2>(qq)] + 1, 0, 0, size);
      auto dd = d1 % pp + d2 % pp + (d1 / pp + d2 / pp) * std::get<0>(qq);
      ret[std::get<3>(qq)] = dd;
    }
    for (auto &che : ce[i]) {
      update(che.first, che.second);
    }
  }

  for (auto r : ret)
    std::cout << r << std::endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using i64 = long long;

struct Edge {
  int to, c, d;
  Edge(int to, int c, int d) : to(to), c(c), d(d) {}
};

constexpr int size = 1 << 18;
i64 dat[size * 2 - 1];

auto query(int a, int b, int k, int l, int r) {
  if (r <= a || b <= l)
    return 0ll;
  if (a <= l && r <= b)
    return dat[k];
  return query(a, b, k * 2 + 1, l, (l + r) / 2) +
         query(a, b, k * 2 + 2, (l + r) / 2, r);
}

void update(int i, i64 x) {
  i += size - 1;
  dat[i] = x;
  while (i) {
    i = (i - 1) / 2;
    dat[i] = dat[i * 2 + 1] + dat[i * 2 + 2];
  }
}

auto dig(int k) {
  if (k >= size - 1)
    return dat[k];
  return dat[k] = dig(k * 2 + 1) + dig(k * 2 + 2);
}

void build(const std::deque<i64> &v) {
  memset(dat, 0, sizeof(dat));
  for (int i = 0; i < v.size(); i++) {
    dat[i + size - 1] = v[i];
  }
  dig(0);
}

std::vector<std::deque<Edge>> g;
std::vector<std::deque<std::pair<int, int>>> ce;
std::deque<i64> euler_tour;
std::vector<int> estart, depth;

int par[100010][17];

void dfs(int v, int p, int c, int j) {
  estart[v] = euler_tour.size() - 1;
  for (auto &e : g[v]) {
    if (e.to == p)
      continue;
    ce[e.c].emplace_back(euler_tour.size(), e.d);
    euler_tour.push_back(e.d);
    depth[e.to] = depth[v] + 1;
    par[e.to][0] = v;
    dfs(e.to, v, e.c, e.d);
  }
  ce[c].emplace_back(euler_tour.size(), -j);
  euler_tour.push_back(-j);
}

int main() {
  int n, q;
  std::cin >> n >> q;
  g.resize(n);
  ce.resize(n);
  estart.resize(n, -1);
  depth.resize(n, -1);
  for (int i = 1; i < n; i++) {
    int u, v, c, d;
    std::cin >> u >> v >> c >> d;
    --u;
    --v;
    g[u].emplace_back(v, c, d);
    g[v].emplace_back(u, c, d);
  }

  for (int i = 0; i < n; i++)
    for (int j = 0; j < 17; j++)
      par[i][j] = -1;
  euler_tour.emplace_back(0);
  dfs(0, -1, 0, 0);
  build(euler_tour);

  for (int i = 0; i + 1 < 17; i++)
    for (int j = 0; j < n; j++) {
      if (par[j][i] < 0)
        continue;
      par[j][i + 1] = par[par[j][i]][i];
    }

  std::vector<std::deque<std::tuple<int, int, int, int>>> cq(n);
  for (int i = 0; i < q; i++) {
    int x, y, u, v;
    std::cin >> x >> y >> u >> v;
    cq[x].emplace_back(y, u - 1, v - 1, i);
  }

  constexpr i64 pp = 10000000000;
  auto sgn = [](auto t) { return t > 0 ? 1 : -1; };

  std::vector<int> ret(q);
  for (int i = 1; i < n; i++) {
    for (auto &che : ce[i]) {
      update(che.first, sgn(che.second) * pp);
    }
    for (auto &qq : cq[i]) {
      auto u = std::get<1>(qq), v = std::get<2>(qq);

      if (depth[u] > depth[v])
        std::swap(u, v);
      auto diff = depth[v] - depth[u];
      for (int i = 16; i >= 0; i--) {
        if (diff & (1 << i))
          v = par[v][i];
      }

      int l = -1, r = n;
      while (r - l > 1) {
        auto k = (l + r) / 2;
        int a = u, b = v;
        bool flg = a == b;
        for (int i = 16; !flg && i >= 0; i--) {
          if ((k & (1 << i)) == 0)
            continue;
          a = par[a][i];
          b = par[b][i];
          if (a == b)
            flg = true;
        }
        if (flg)
          r = k;
        else
          l = k;
      }

      int lca = v;
      for (int i = 16; i >= 0; i--) {
        if (r & (1 << i))
          lca = par[lca][i];
      }

      auto d1 = query(estart[lca] + 1, estart[std::get<1>(qq)] + 1, 0, 0, size),
           d2 = query(estart[lca] + 1, estart[std::get<2>(qq)] + 1, 0, 0, size);
      auto dd = d1 % pp + d2 % pp + (d1 / pp + d2 / pp) * std::get<0>(qq);
      ret[std::get<3>(qq)] = dd;
    }
    for (auto &che : ce[i]) {
      update(che.first, che.second);
    }
  }

  for (auto r : ret)
    std::cout << r << std::endl;

  return 0;
}