Problem p02986 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

const int N = 100 * 1000 + 17;
const int MOD = 1000 * 1000 * 1000 + 7;
const int MAGIC = 512;

struct edge {
  int u, v, col, len;
  edge() = default;
  edge(int u, int v, int c, int l) : u(u), v(v), col(c), len(l) {}
};

int n, q, t = 0;
int L[N], R[N];
int up[20][N];
vector<pair<long long, int>> sum[N];
vector<edge> g[N];
vector<edge> E[N];

bool read() {
  if (!(cin >> n >> q))
    return false;

  sum[n].resize(n);

  for (int i = 0; i < n - 1; ++i) {
    int u, v, col, len;
    cin >> u >> v >> col >> len;
    g[u - 1].emplace_back(u - 1, v - 1, col, len);
    g[v - 1].emplace_back(v - 1, u - 1, col, len);
    E[col - 1].emplace_back(u - 1, v - 1, col, len);
  }

  return true;
}

pair<long long, int> operator+(const pair<long long, int> &a,
                               const pair<long long, int> &b) {
  return {a.first + b.first, a.second + b.second};
}

void predfs(int v, int pr) {
  up[v][0] = pr;
  L[v] = t++;

  for (const auto &e : g[v])
    if (e.v != pr)
      predfs(e.v, v);

  R[v] = t - 1;
}

void dfs(int v, int pr, int id) {
  for (const auto &e : g[v])
    if (e.v != pr) {
      if (id != n)
        sum[id][e.v] = sum[id][e.v] + sum[id][v];
      else
        sum[id][e.v] = sum[id][v] + make_pair(e.len, 1);

      dfs(e.v, v, id);
    }
}

bool isanc(int u, int v) { return L[u] <= L[v] && R[v] <= R[u]; }

bool btwn(int u, int v, int U, int V) {
  if (!isanc(u, U) || !isanc(V, u))
    return false;

  if (!isanc(v, U) || !isanc(V, v))
    return false;

  return true;
}

int lca(int u, int v) {
  if (isanc(u, v))
    return u;

  if (isanc(v, u))
    return v;

  for (int i = 19; i >= 0; --i)
    if (!isanc(up[u][i], v))
      u = up[u][i];

  return up[u][0];
}

void solve() {
  predfs(0, 0);

  for (int i = 0; i < n; ++i)
    if (E[i].size() >= MAGIC) {
      sum[i].resize(n);

      for (const auto &e : E[i])
        sum[i][isanc(e.u, e.v) ? e.v : e.u] = {e.len, 1};

      dfs(0, 0, i);
    }

  sum[n].resize(n);
  dfs(0, 0, n);

  for (int k = 1; k < 20; ++k)
    for (int i = 0; i < n; ++i)
      up[i][k] = up[up[i][k - 1]][k - 1];

  while (q-- > 0) {
    int col, w, u, v;
    cin >> col >> w >> u >> v;
    --col, --u, --v;
    auto anc = lca(u, v);
    auto res = sum[n][u].first + sum[n][v].first - 2 * sum[n][anc].first;

    if (E[col].size() >= MAGIC) {
      res -= sum[col][u].first + sum[col][v].first - 2 * sum[col][anc].first;
      res += w * (sum[col][u].second + sum[col][v].second -
                  2 * sum[col][anc].second);
    } else {
      for (const auto &e : E[col])
        if (btwn(e.u, e.v, u, anc) || btwn(e.u, e.v, v, anc))
          res += w - e.len;
    }

    cout << res << endl;
  }
}

int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  while (read())
    solve();

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

const int N = 100 * 1000 + 17;
const int MOD = 1000 * 1000 * 1000 + 7;
const int MAGIC = 512;

struct edge {
  int u, v, col, len;
  edge() = default;
  edge(int u, int v, int c, int l) : u(u), v(v), col(c), len(l) {}
};

int n, q, t = 0;
int L[N], R[N];
int up[N][20];
vector<pair<long long, int>> sum[N];
vector<edge> g[N];
vector<edge> E[N];

bool read() {
  if (!(cin >> n >> q))
    return false;

  sum[n].resize(n);

  for (int i = 0; i < n - 1; ++i) {
    int u, v, col, len;
    cin >> u >> v >> col >> len;
    g[u - 1].emplace_back(u - 1, v - 1, col, len);
    g[v - 1].emplace_back(v - 1, u - 1, col, len);
    E[col - 1].emplace_back(u - 1, v - 1, col, len);
  }

  return true;
}

pair<long long, int> operator+(const pair<long long, int> &a,
                               const pair<long long, int> &b) {
  return {a.first + b.first, a.second + b.second};
}

void predfs(int v, int pr) {
  up[v][0] = pr;
  L[v] = t++;

  for (const auto &e : g[v])
    if (e.v != pr)
      predfs(e.v, v);

  R[v] = t - 1;
}

void dfs(int v, int pr, int id) {
  for (const auto &e : g[v])
    if (e.v != pr) {
      if (id != n)
        sum[id][e.v] = sum[id][e.v] + sum[id][v];
      else
        sum[id][e.v] = sum[id][v] + make_pair(e.len, 1);

      dfs(e.v, v, id);
    }
}

bool isanc(int u, int v) { return L[u] <= L[v] && R[v] <= R[u]; }

bool btwn(int u, int v, int U, int V) {
  if (!isanc(u, U) || !isanc(V, u))
    return false;

  if (!isanc(v, U) || !isanc(V, v))
    return false;

  return true;
}

int lca(int u, int v) {
  if (isanc(u, v))
    return u;

  if (isanc(v, u))
    return v;

  for (int i = 19; i >= 0; --i)
    if (!isanc(up[u][i], v))
      u = up[u][i];

  return up[u][0];
}

void solve() {
  predfs(0, 0);

  for (int i = 0; i < n; ++i)
    if (E[i].size() >= MAGIC) {
      sum[i].resize(n);

      for (const auto &e : E[i])
        sum[i][isanc(e.u, e.v) ? e.v : e.u] = {e.len, 1};

      dfs(0, 0, i);
    }

  sum[n].resize(n);
  dfs(0, 0, n);

  for (int k = 1; k < 20; ++k)
    for (int i = 0; i < n; ++i)
      up[i][k] = up[up[i][k - 1]][k - 1];

  while (q-- > 0) {
    int col, w, u, v;
    cin >> col >> w >> u >> v;
    --col, --u, --v;
    auto anc = lca(u, v);
    auto res = sum[n][u].first + sum[n][v].first - 2 * sum[n][anc].first;

    if (E[col].size() >= MAGIC) {
      res -= sum[col][u].first + sum[col][v].first - 2 * sum[col][anc].first;
      res += w * (sum[col][u].second + sum[col][v].second -
                  2 * sum[col][anc].second);
    } else {
      for (const auto &e : E[col])
        if (btwn(e.u, e.v, u, anc) || btwn(e.u, e.v, v, anc))
          res += w - e.len;
    }

    cout << res << endl;
  }
}

int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  while (read())
    solve();

  return 0;
}