Problem p02986 (C++)

Buggy submission (status: Runtime Error):
#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>
#define F first
#define S second
#define vec vector
#define ms multiset
#define pb push_back
#define pll pair<ll, ll>
#define pdd pair<ld, ld>
#define pq priority_queue
#define umap unordered_map
#define uset unordered_set
#define pii pair<int, int>
#define pnn pair<Node *, Node *>
#define uid uniform_int_distribution
#define FILE                                                                   \
  ifstream in("board.in");                                                     \
  ofstream out("board.out");
#define fast                                                                   \
  cin.tie(0);                                                                  \
  cout.tie(0);                                                                 \
  cin.sync_with_stdio(0);                                                      \
  cout.sync_with_stdio(0);
using namespace std;
typedef string str;
typedef long long ll;
typedef long double ld;
mt19937 rnd(chrono::steady_clock::now()
                .time_since_epoch()
                .count()); // uid<int> u1(5, 10); u1(rnd);

struct edg {
  int y, c, d;
  edg(int a, int b, int cc) {
    y = a;
    c = b;
    d = cc;
  }
};

struct Node {
  Node *l, *r;
  pii p;

  Node(Node *a, Node *b) {
    l = a;
    r = b;
    p = {a->p.F + b->p.F, a->p.S + b->p.S};
  }

  Node(Node *a, Node *b, pii pp) {
    l = a;
    r = b;
    p = pp;
  }

  Node(Node *n) {
    l = n->l;
    r = n->r;
    p = n->p;
  }
};

Node *add(int l, int r, int pos, Node *n, int val) {
  Node *cp = n ? new Node(n) : new Node(0, 0, {0, 0});
  if (l == r) {
    cp->p.F++;
    cp->p.S += val;
    return cp;
  }
  int md = (l + r) / 2;
  if (pos <= md)
    cp->l = add(l, md, pos, cp->l, val);
  else
    cp->r = add(md + 1, r, pos, cp->r, val);
  return cp;
}

pii get(int l, int r, int pos, Node *n) {
  if (!n)
    return {0, 0};
  if (l == r)
    return n->p;
  int md = (l + r) / 2;
  if (pos <= md)
    return get(l, md, pos, n->l);
  else
    return get(md + 1, r, pos, n->r);
}

int a, z, SIZE = 1e5 + 5;
vec<vec<edg>> l;
vec<vec<int>> n;
vec<int> cl, dl, prs, dep, mx;
vec<Node *> m;

void init(int v, int pr, int c, int d, int depp) {
  cl[v] = c;
  dl[v] = d;
  dep[v] = depp;
  n[0][v] = pr;
  if (pr != -1) {
    m[v] = add(0, SIZE, c, m[pr], d);
    prs[v] = prs[pr] + d;
  }
  for (edg h : l[v]) {
    if (h.y == pr)
      continue;
    init(h.y, v, h.c, h.d, depp + 1);
  }
}

int lca(int x, int y) {
  if (dep[x] > dep[y])
    swap(x, y);
  for (int d = dep[y] - dep[x]; d; d -= 1 << mx[d])
    y = n[mx[d]][y];
  for (int q = 16; q >= 0; q--) {
    int px = n[q][x], py = n[q][y];
    if (px != py || q == 0)
      x = px, y = py;
  }
  return x == y ? x : n[0][x];
}

int main() {
  fast;
  mx = vec<int>(SIZE);
  for (int q = 2; q < SIZE; q++)
    mx[q] = 2 << mx[q - 1] > q ? mx[q - 1] : mx[q - 1] + 1;
  cin >> a >> z;
  m = vec<Node *>(a);
  dep = vec<int>(a);
  cl = vec<int>(a);
  dl = vec<int>(a);
  prs = vec<int>(a);
  n = vec<vec<int>>(17, vec<int>(a));
  l = vec<vec<edg>>(a, vec<edg>());
  for (int q = 0; q < a - 1; q++) {
    int x, y, c, d;
    cin >> x >> y >> c >> d;
    x--;
    y--;
    l[x].pb(edg(y, c, d));
    l[y].pb(edg(x, c, d));
  }
  m[0] = new Node(0, 0, {0, 0});
  init(0, -1, 0, 0, 0);
  for (int q = 1; q < 17; q++) {
    for (int w = 0; w < a; w++) {
      n[q][w] = n[q - 1][w] == -1 ? -1 : n[q - 1][n[q - 1][w]];
    }
  }
  for (; z; z--) {
    int x, y, c, d;
    cin >> c >> d >> x >> y;
    x--;
    y--;
    int lc = lca(x, y);
    int sum = prs[x] + prs[y] - 2 * prs[lc];
    pii px = get(0, SIZE, c, m[x]);
    pii py = get(0, SIZE, c, m[y]);
    pii pl = get(0, SIZE, c, m[lc]);
    pii po = {px.F + py.F - 2 * pl.F, px.S + py.S - 2 * pl.S};
    cout << sum - po.S + po.F * d << "\n";
  }
}

Fixed submission:
#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>
#define F first
#define S second
#define vec vector
#define ms multiset
#define pb push_back
#define pll pair<ll, ll>
#define pdd pair<ld, ld>
#define pq priority_queue
#define umap unordered_map
#define uset unordered_set
#define pii pair<int, int>
#define pnn pair<Node *, Node *>
#define uid uniform_int_distribution
#define FILE                                                                   \
  ifstream in("board.in");                                                     \
  ofstream out("board.out");
#define fast                                                                   \
  cin.tie(0);                                                                  \
  cout.tie(0);                                                                 \
  cin.sync_with_stdio(0);                                                      \
  cout.sync_with_stdio(0);
using namespace std;
typedef string str;
typedef long long ll;
typedef long double ld;
mt19937 rnd(chrono::steady_clock::now()
                .time_since_epoch()
                .count()); // uid<int> u1(5, 10); u1(rnd);

struct edg {
  int y, c, d;
  edg(int a, int b, int cc) {
    y = a;
    c = b;
    d = cc;
  }
};

struct Node {
  Node *l, *r;
  pii p;

  Node(Node *a, Node *b) {
    l = a;
    r = b;
    p = {a->p.F + b->p.F, a->p.S + b->p.S};
  }

  Node(Node *a, Node *b, pii pp) {
    l = a;
    r = b;
    p = pp;
  }

  Node(Node *n) {
    l = n->l;
    r = n->r;
    p = n->p;
  }
};

Node *add(int l, int r, int pos, Node *n, int val) {
  Node *cp = n ? new Node(n) : new Node(0, 0, {0, 0});
  if (l == r) {
    cp->p.F++;
    cp->p.S += val;
    return cp;
  }
  int md = (l + r) / 2;
  if (pos <= md)
    cp->l = add(l, md, pos, cp->l, val);
  else
    cp->r = add(md + 1, r, pos, cp->r, val);
  return cp;
}

pii get(int l, int r, int pos, Node *n) {
  if (!n)
    return {0, 0};
  if (l == r)
    return n->p;
  int md = (l + r) / 2;
  if (pos <= md)
    return get(l, md, pos, n->l);
  else
    return get(md + 1, r, pos, n->r);
}

int a, z, SIZE = 1e5 + 5;
vec<vec<edg>> l;
vec<vec<int>> n;
vec<int> cl, dl, prs, dep, mx;
vec<Node *> m;

void init(int v, int pr, int c, int d, int depp) {
  cl[v] = c;
  dl[v] = d;
  dep[v] = depp;
  n[0][v] = pr;
  if (pr != -1) {
    m[v] = add(0, SIZE, c, m[pr], d);
    prs[v] = prs[pr] + d;
  }
  for (edg h : l[v]) {
    if (h.y == pr)
      continue;
    init(h.y, v, h.c, h.d, depp + 1);
  }
}

int lca(int x, int y) {
  if (dep[x] > dep[y])
    swap(x, y);
  for (int d = dep[y] - dep[x]; d; d -= 1 << mx[d])
    y = n[mx[d]][y];
  for (int q = 16; x != y && q >= 0; q--) {
    int px = n[q][x], py = n[q][y];
    if (px != py || q == 0)
      x = px, y = py;
  }
  return x == y ? x : n[0][x];
}

int main() {
  fast;
  mx = vec<int>(SIZE);
  for (int q = 2; q < SIZE; q++)
    mx[q] = 2 << mx[q - 1] > q ? mx[q - 1] : mx[q - 1] + 1;
  cin >> a >> z;
  m = vec<Node *>(a);
  dep = vec<int>(a);
  cl = vec<int>(a);
  dl = vec<int>(a);
  prs = vec<int>(a);
  n = vec<vec<int>>(17, vec<int>(a));
  l = vec<vec<edg>>(a, vec<edg>());
  for (int q = 0; q < a - 1; q++) {
    int x, y, c, d;
    cin >> x >> y >> c >> d;
    x--;
    y--;
    l[x].pb(edg(y, c, d));
    l[y].pb(edg(x, c, d));
  }
  m[0] = new Node(0, 0, {0, 0});
  init(0, -1, 0, 0, 0);
  for (int q = 1; q < 17; q++) {
    for (int w = 0; w < a; w++) {
      n[q][w] = n[q - 1][w] == -1 ? -1 : n[q - 1][n[q - 1][w]];
    }
  }
  for (; z; z--) {
    int x, y, c, d;
    cin >> c >> d >> x >> y;
    x--;
    y--;
    int lc = lca(x, y);
    int sum = prs[x] + prs[y] - 2 * prs[lc];
    pii px = get(0, SIZE, c, m[x]);
    pii py = get(0, SIZE, c, m[y]);
    pii pl = get(0, SIZE, c, m[lc]);
    pii po = {px.F + py.F - 2 * pl.F, px.S + py.S - 2 * pl.S};
    cout << sum - po.S + po.F * d << "\n";
  }
}