Problem p02986 (C++)

Buggy submission (status: Runtime Error):
/*
luogu AT4809
*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define mid (l + r >> 1)

int n, q;
int ee, h[100005], nex[100005 << 1], to[100005 << 1], val[100005 << 1],
    col[100005 << 1];
int dis[100005], v[100005], c[100005];
int dfn, mark[100005], fa[100005], son[100005], dep[100005], top[100005],
    siz[100005];
int cnt, root[100005];
struct segtree {
  int l, r;
  int num, sum;
  void init() { num = sum = 0; }
  segtree operator+(segtree b) {
    segtree res;
    res.num = num + b.num;
    res.sum = sum + b.sum;
    return res;
  }
} dat[100005 << 2];

void addedge(int x, int y, int z, int w) {
  nex[++ee] = h[x];
  to[ee] = y;
  val[ee] = z;
  col[ee] = w;
  h[x] = ee;
}

void dfs1(int x, int pre) {
  siz[x] = 1;
  fa[x] = pre;
  dep[x] = dep[pre] + 1;
  for (int i = h[x]; i; i = nex[i])
    if (to[i] != pre) {
      v[to[i]] = val[i], c[to[i]] = col[i];
      dis[to[i]] = dis[x] + val[i];
      dfs1(to[i], x);
      if (siz[to[i]] > siz[son[x]])
        son[x] = to[i];
      siz[x] += siz[to[i]];
    }
}

void dfs2(int x, int tp) {
  mark[x] = ++dfn;
  top[x] = tp;
  if (!son[x])
    return;
  dfs2(son[x], tp);
  for (int i = h[x]; i; i = nex[i])
    if (to[i] != fa[x] && to[i] != son[x])
      dfs2(to[i], to[i]);
}

void modify(int &o, int l, int r, int x, int v) {
  if (!o)
    o = ++cnt;
  dat[o].num++;
  dat[o].sum += v;
  if (l == x && r == x)
    return;
  if (x <= mid)
    modify(dat[o].l, l, mid, x, v);
  else
    modify(dat[o].r, mid + 1, r, x, v);
}

segtree query(int o, int l, int r, int ql, int qr) {
  if (l >= ql && r <= qr)
    return dat[o];
  segtree res;
  res.init();
  if (ql <= mid)
    res = res + query(dat[o].l, l, mid, ql, qr);
  if (qr > mid)
    res = res + query(dat[o].r, mid + 1, r, ql, qr);
  return res;
}

int query_(int c, int x, int y, int d) {
  int l = dis[x] + dis[y];
  segtree res;
  res.init();
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]])
      swap(x, y);
    res = res + query(root[c], 1, n, mark[top[x]], mark[x]);
    x = fa[top[x]];
  }
  if (dep[x] < dep[y])
    swap(x, y);
  if (x != y)
    res = res + query(root[c], 1, n, mark[y] + 1, mark[x]);
  return l - 2 * dis[y] - res.sum + res.num * d;
}

signed main() {
  cin >> n >> q;
  for (int i = 1, x, y, z, w;
       i < n && scanf("%lld %lld %lld %lld", &x, &y, &z, &w); i++)
    addedge(x, y, w, z), addedge(y, x, w, z);
  dfs1(1, 0), dfs2(1, 1);
  for (int i = 2; i <= n; i++)
    modify(root[c[i]], 1, n, mark[i], v[i]);
  while (q--) {
    int c, d, x, y;
    scanf("%lld %lld %lld %lld", &c, &d, &x, &y);
    printf("%lld\n", query_(c, x, y, d));
  }

  return 0;
}

Fixed submission:
/*
luogu AT4809
*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define mid (l + r >> 1)

int n, q;
int ee, h[100005], nex[100005 << 1], to[100005 << 1], val[100005 << 1],
    col[100005 << 1];
int dis[100005], v[100005], c[100005];
int dfn, mark[100005], fa[100005], son[100005], dep[100005], top[100005],
    siz[100005];
int cnt, root[100005];
struct segtree {
  int l, r;
  int num, sum;
  void init() { num = sum = 0; }
  segtree operator+(segtree b) {
    segtree res;
    res.num = num + b.num;
    res.sum = sum + b.sum;
    return res;
  }
} dat[100005 << 5];

void addedge(int x, int y, int z, int w) {
  nex[++ee] = h[x];
  to[ee] = y;
  val[ee] = z;
  col[ee] = w;
  h[x] = ee;
}

void dfs1(int x, int pre) {
  siz[x] = 1;
  fa[x] = pre;
  dep[x] = dep[pre] + 1;
  for (int i = h[x]; i; i = nex[i])
    if (to[i] != pre) {
      v[to[i]] = val[i], c[to[i]] = col[i];
      dis[to[i]] = dis[x] + val[i];
      dfs1(to[i], x);
      if (siz[to[i]] > siz[son[x]])
        son[x] = to[i];
      siz[x] += siz[to[i]];
    }
}

void dfs2(int x, int tp) {
  mark[x] = ++dfn;
  top[x] = tp;
  if (!son[x])
    return;
  dfs2(son[x], tp);
  for (int i = h[x]; i; i = nex[i])
    if (to[i] != fa[x] && to[i] != son[x])
      dfs2(to[i], to[i]);
}

void modify(int &o, int l, int r, int x, int v) {
  if (!o)
    o = ++cnt;
  dat[o].num++;
  dat[o].sum += v;
  if (l == x && r == x)
    return;
  if (x <= mid)
    modify(dat[o].l, l, mid, x, v);
  else
    modify(dat[o].r, mid + 1, r, x, v);
}

segtree query(int o, int l, int r, int ql, int qr) {
  if (l >= ql && r <= qr)
    return dat[o];
  segtree res;
  res.init();
  if (ql <= mid)
    res = res + query(dat[o].l, l, mid, ql, qr);
  if (qr > mid)
    res = res + query(dat[o].r, mid + 1, r, ql, qr);
  return res;
}

int query_(int c, int x, int y, int d) {
  int l = dis[x] + dis[y];
  segtree res;
  res.init();
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]])
      swap(x, y);
    res = res + query(root[c], 1, n, mark[top[x]], mark[x]);
    x = fa[top[x]];
  }
  if (dep[x] < dep[y])
    swap(x, y);
  if (x != y)
    res = res + query(root[c], 1, n, mark[y] + 1, mark[x]);
  return l - 2 * dis[y] - res.sum + res.num * d;
}

signed main() {
  cin >> n >> q;
  for (int i = 1, x, y, z, w;
       i < n && scanf("%lld %lld %lld %lld", &x, &y, &z, &w); i++)
    addedge(x, y, w, z), addedge(y, x, w, z);
  dfs1(1, 0), dfs2(1, 1);
  for (int i = 2; i <= n; i++)
    modify(root[c[i]], 1, n, mark[i], v[i]);
  while (q--) {
    int c, d, x, y;
    scanf("%lld %lld %lld %lld", &c, &d, &x, &y);
    printf("%lld\n", query_(c, x, y, d));
  }

  return 0;
}