Problem p02986 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
const int maxm = 1e6 + 10;
const int maxn = 133334;
typedef long long ll;
struct node {
  int s, e, c, w, next;
} edge[maxn];
int head[maxn], len;
int n, q;
void init() {
  memset(head, -1, sizeof(head));
  len = 0;
}
void add(int s, int e, int c, int w) {
  edge[len].s = s;
  edge[len].e = e;
  edge[len].w = w;
  edge[len].c = c;
  edge[len].next = head[s];
  head[s] = len++;
}
int son[maxn], top[maxn], tid[maxn], fat[maxn], siz[maxn], dep[maxn], rak[maxn];
int dfx;
void dfs1(int x, int fa, int d) {
  siz[x] = 1, son[x] = -1, fat[x] = fa, dep[x] = d;
  for (int i = head[x]; i != -1; i = edge[i].next) {
    int y = edge[i].e;
    if (y == fa)
      continue;
    dfs1(y, x, d + 1);
    siz[x] += siz[y];
    if (son[x] == -1 || siz[y] > siz[son[x]])
      son[x] = y;
  }
}
void dfs2(int x, int c) {
  top[x] = c;
  tid[x] = ++dfx;
  rak[dfx] = x;
  if (son[x] == -1)
    return;
  dfs2(son[x], c);
  for (int i = head[x]; i != -1; i = edge[i].next) {
    int y = edge[i].e;
    if (y == fat[x] || y == son[x])
      continue;
    dfs2(y, y);
  }
}
int cnt, root[maxn], ls[maxn * 40], rs[maxn * 40], num[maxn * 40],
    val[maxn * 40];
struct C {
  int color, dis;
} a[maxn];
void build(C k, int l, int r, int &i) {
  num[++cnt] = num[i] + 1, val[cnt] = val[i] + k.dis, ls[cnt] = ls[i],
  rs[cnt] = rs[i];
  i = cnt;
  if (l == r)
    return;
  int mid = l + r >> 1;
  if (k.color <= mid)
    build(k, l, mid, ls[i]);
  else
    build(k, mid + 1, r, rs[i]);
}
C query(int u, int v, int k, int l, int r) {
  if (l == r) {
    return {num[v] - num[u], val[v] - val[u]};
  }

  int mid = l + r >> 1;
  if (k <= mid)
    return query(ls[u], ls[v], k, l, mid);
  else
    return query(rs[u], rs[v], k, mid + 1, r);
}
int solve(int cr, int dis, int x, int y) {
  C ans = {0, 0};
  int sum = 0;
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]])
      swap(x, y);
    C t = query(root[tid[top[x]] - 1], root[tid[x]], cr, 1, n);
    sum += val[root[tid[x]]] - val[root[tid[top[x]] - 1]];
    ans.color += t.color, ans.dis += t.dis;
    x = fat[top[x]];
  }

  if (x != y) {
    if (dep[x] < dep[y])
      swap(x, y);
    C t = query(root[tid[son[y]] - 1], root[tid[x]], cr, 1, n);
    sum += val[root[tid[x]]] - val[root[tid[son[y]] - 1]];
    ans.color += t.color, ans.dis += t.dis;
  }
  // cout << sum << " " << ans.color << " " << ans.dis << endl;
  return sum - ans.dis + ans.color * dis;
}
void dfs(int l, int r, int i) {
  if (l == r) {
    printf("%d#%d ", num[i], val[i]);
    return;
  }
  int mid = l + r >> 1;
  dfs(l, mid, ls[i]);
  dfs(mid + 1, r, rs[i]);
}
int main() {
  scanf("%d%d", &n, &q);
  init();
  for (int i = 1, x, y, c, d; i < n; i++) {
    scanf("%d%d%d%d", &x, &y, &c, &d);
    add(x, y, c, d);
    add(y, x, c, d);
  }
  dfs1(1, 0, 1);
  dfs2(1, 1);
  for (int i = 0; i < len; i += 2) {
    int x = edge[i].e;
    int y = edge[i].s;
    if (dep[x] < dep[y])
      swap(x, y);
    a[tid[x]] = {edge[i].c, edge[i].w};
  }
  for (int i = 2; i <= dfx; i++) {
    root[i] = root[i - 1];
    build(a[i], 1, n, root[i]);
    // dfs(1, n, root[i]);
  }
  while (q--) {
    int x, y, u, v;
    scanf("%d%d%d%d", &x, &y, &u, &v);
    printf("%d\n", solve(x, y, u, v));
  }
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
const int maxm = 1e6 + 10;
const int maxn = 3e5 + 10;
typedef long long ll;
struct node {
  int s, e, c, w, next;
} edge[maxn];
int head[maxn], len;
int n, q;
void init() {
  memset(head, -1, sizeof(head));
  len = 0;
}
void add(int s, int e, int c, int w) {
  edge[len].s = s;
  edge[len].e = e;
  edge[len].w = w;
  edge[len].c = c;
  edge[len].next = head[s];
  head[s] = len++;
}
int son[maxn], top[maxn], tid[maxn], fat[maxn], siz[maxn], dep[maxn], rak[maxn];
int dfx;
void dfs1(int x, int fa, int d) {
  siz[x] = 1, son[x] = -1, fat[x] = fa, dep[x] = d;
  for (int i = head[x]; i != -1; i = edge[i].next) {
    int y = edge[i].e;
    if (y == fa)
      continue;
    dfs1(y, x, d + 1);
    siz[x] += siz[y];
    if (son[x] == -1 || siz[y] > siz[son[x]])
      son[x] = y;
  }
}
void dfs2(int x, int c) {
  top[x] = c;
  tid[x] = ++dfx;
  rak[dfx] = x;
  if (son[x] == -1)
    return;
  dfs2(son[x], c);
  for (int i = head[x]; i != -1; i = edge[i].next) {
    int y = edge[i].e;
    if (y == fat[x] || y == son[x])
      continue;
    dfs2(y, y);
  }
}
int cnt, root[maxn], ls[maxn * 40], rs[maxn * 40], num[maxn * 40],
    val[maxn * 40];
struct C {
  int color, dis;
} a[maxn];
void build(C k, int l, int r, int &i) {
  num[++cnt] = num[i] + 1, val[cnt] = val[i] + k.dis, ls[cnt] = ls[i],
  rs[cnt] = rs[i];
  i = cnt;
  if (l == r)
    return;
  int mid = l + r >> 1;
  if (k.color <= mid)
    build(k, l, mid, ls[i]);
  else
    build(k, mid + 1, r, rs[i]);
}
C query(int u, int v, int k, int l, int r) {
  if (l == r) {
    return {num[v] - num[u], val[v] - val[u]};
  }

  int mid = l + r >> 1;
  if (k <= mid)
    return query(ls[u], ls[v], k, l, mid);
  else
    return query(rs[u], rs[v], k, mid + 1, r);
}
int solve(int cr, int dis, int x, int y) {
  C ans = {0, 0};
  int sum = 0;
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]])
      swap(x, y);
    C t = query(root[tid[top[x]] - 1], root[tid[x]], cr, 1, n);
    sum += val[root[tid[x]]] - val[root[tid[top[x]] - 1]];
    ans.color += t.color, ans.dis += t.dis;
    x = fat[top[x]];
  }

  if (x != y) {
    if (dep[x] < dep[y])
      swap(x, y);
    C t = query(root[tid[son[y]] - 1], root[tid[x]], cr, 1, n);
    sum += val[root[tid[x]]] - val[root[tid[son[y]] - 1]];
    ans.color += t.color, ans.dis += t.dis;
  }
  // cout << sum << " " << ans.color << " " << ans.dis << endl;
  return sum - ans.dis + ans.color * dis;
}
void dfs(int l, int r, int i) {
  if (l == r) {
    printf("%d#%d ", num[i], val[i]);
    return;
  }
  int mid = l + r >> 1;
  dfs(l, mid, ls[i]);
  dfs(mid + 1, r, rs[i]);
}
int main() {
  scanf("%d%d", &n, &q);
  init();
  for (int i = 1, x, y, c, d; i < n; i++) {
    scanf("%d%d%d%d", &x, &y, &c, &d);
    add(x, y, c, d);
    add(y, x, c, d);
  }
  dfs1(1, 0, 1);
  dfs2(1, 1);
  for (int i = 0; i < len; i += 2) {
    int x = edge[i].e;
    int y = edge[i].s;
    if (dep[x] < dep[y])
      swap(x, y);
    a[tid[x]] = {edge[i].c, edge[i].w};
  }
  for (int i = 2; i <= dfx; i++) {
    root[i] = root[i - 1];
    build(a[i], 1, n, root[i]);
    // dfs(1, n, root[i]);
  }
  while (q--) {
    int x, y, u, v;
    scanf("%d%d%d%d", &x, &y, &u, &v);
    printf("%d\n", solve(x, y, u, v));
  }
}