Problem p02986 (C++)

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

using namespace std;

const int OO = 1e9;
const double EPS = 1e-9;

#define ndl cout << '\n'
#define sz(v) int(v.size())
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define present(a, x) (a.find(x) != a.end())
#ifdef LOCAL
#define db(...)                                                                \
  ({                                                                           \
    cout << "> Line " << __LINE__ << ": ";                                     \
    _db(#__VA_ARGS__, __VA_ARGS__);                                            \
  })
#else
#define db(...) true
#endif

template <class T> void _db(const char *dbStr, T e) {
  cout << dbStr << " = " << e << endl;
}
template <class T, class... L> void _db(const char *dbStr, T e, L... r) {
  while (*dbStr != ',')
    cout << *dbStr++;
  cout << " = " << e << ',';
  _db(dbStr + 1, r...);
}
template <class S, class T>
ostream &operator<<(ostream &o, const map<S, T> &v) {
  o << "[";
  int i = 0;
  for (const pair<S, T> &pr : v)
    o << (!i++ ? "" : ", ") << "{" << pr.fs << " : " << pr.sc << "}";
  return o << "]";
}
template <template <class, class...> class S, class T, class... L>
ostream &operator<<(ostream &o, const S<T, L...> &v) {
  o << "[";
  int i = 0;
  for (const auto &e : v)
    o << (!i++ ? "" : ", ") << e;
  return o << "]";
}
template <class S, class T>
ostream &operator<<(ostream &o, const pair<S, T> &pr) {
  return o << "(" << pr.fs << ", " << pr.sc << ")";
}
ostream &operator<<(ostream &o, const string &s) {
  for (const char &c : s)
    o << c;
  return o;
}

template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;
template <class T> using VVV = VV<V<T>>;
using ll = long long;
using pii = pair<int, int>;
using vi = V<int>;
using vii = V<pii>;
using vvi = VV<int>;
using mii = map<int, int>;
using umii = unordered_map<int, int>;
using si = set<int>;
using usi = unordered_set<int>;

int N, Q;
V<V<pair<int, pii>>> adj; // (v, (c, d))
vi D, E, W;
V<V<pair<int, pair<int, pii>>>> nodeQuery; // (ID, (c, (y, coef.)))
vi ans;

#define LOG_TWO_N 10

struct SparseTable {
  vi A;
  vvi SpT;
  vvi mnIdx;
  SparseTable(const vi &_A) {
    A = _A;
    int n = A.size();
    SpT.assign(n, vi(LOG_TWO_N));
    mnIdx.assign(n, vi(LOG_TWO_N));
    for (int i = 0; i < n; i++)
      SpT[i][0] = i, mnIdx[i][0] = i;
    for (int j = 1; (1 << j) <= n; ++j)
      for (int i = 0; i + (1 << j) - 1 < n; ++i)
        if (A[SpT[i][j - 1]] < A[SpT[i + (1 << (j - 1))][j - 1]])
          SpT[i][j] = SpT[i][j - 1], mnIdx[i][j] = mnIdx[i][j - 1];
        else
          SpT[i][j] = SpT[i + (1 << (j - 1))][j - 1],
          mnIdx[i][j] = mnIdx[i + (1 << (j - 1))][j - 1];
  }
  SparseTable() {}
  int query(int i, int j) {
    int k = floor(log2(j - i + 1));
    if (A[SpT[i][k]] <= A[SpT[j - (1 << k) + 1][k]])
      return SpT[i][k];
    else
      return SpT[j - (1 << k) + 1][k];
  }
  int queryIdx(int i, int j) {
    int k = floor(log2(j - i + 1));
    if (A[SpT[i][k]] <= A[SpT[j - (1 << k) + 1][k]])
      return mnIdx[i][k];
    else
      return mnIdx[j - (1 << k) + 1][k];
  }
};

struct LCA {
  int n, idx;
  vi dep, seq, fsOcc;
  SparseTable RMQ;
  void dfs(int node, int depth, int parent) {
    fsOcc[node] = idx;
    seq[idx] = node;
    dep[idx++] = depth;
    for (auto &pr : adj[node])
      if (pr.fs != parent) {
        dfs(pr.fs, depth + 1, node);
        seq[idx] = node;
        dep[idx++] = depth;
      }
  }
  LCA(int _n, int root) {
    n = _n + 1;
    dep.assign(2 * n, 0);
    seq.assign(2 * n, 0);
    fsOcc.assign(n, 0);
    idx = 0;
    dfs(root, 0, -1);
    RMQ = SparseTable(dep);
  }
  int query(int u, int v) {
    if (fsOcc[u] > fsOcc[v])
      swap(u, v);
    return seq[RMQ.query(fsOcc[u], fsOcc[v])];
  }
};

void dfs(int node, int par, int dist) {
  db(node, E, W);
  D[node] = dist;
  for (auto &data : nodeQuery[node])
    ans[data.fs] += data.sc.sc.sc *
                    (D[node] + data.sc.sc.fs * E[data.sc.fs] - W[data.sc.fs]);

  for (auto &pr : adj[node])
    if (pr.fs != par) {
      ++E[pr.sc.fs];
      W[pr.sc.fs] += pr.sc.sc;
      dfs(pr.fs, node, dist + pr.sc.sc);
      --E[pr.sc.fs];
      W[pr.sc.fs] -= pr.sc.sc;
    }
}

int main() {
#ifdef LOCAL
  auto stTime = clock();
  //	freopen("in.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cout.precision(10);
  cin.tie(0);

  cin >> N >> Q;
  adj.assign(N + 1, V<pair<int, pii>>());
  nodeQuery.assign(N + 1, V<pair<int, pair<int, pii>>>());
  D.assign(N + 1, 0);
  E.assign(N, 0);
  W.assign(N, 0);
  int u, v, c, d;
  for (int i = 0; i < N - 1; ++i) {
    cin >> u >> v >> c >> d;
    adj[u].pb(mp(v, mp(c, d)));
    adj[v].pb(mp(u, mp(c, d)));
  }
  LCA lca(N, 1);
  ans.assign(Q, 0);
  int x, y;
  for (int i = 0; i < Q; ++i) {
    cin >> x >> y >> u >> v;
    nodeQuery[u].pb(mp(i, mp(x, mp(y, 1))));
    nodeQuery[v].pb(mp(i, mp(x, mp(y, 1))));
    nodeQuery[lca.query(u, v)].pb(mp(i, mp(x, mp(y, -2))));
  }
  dfs(1, -1, 0);
  db(D);
  for (auto &lilAns : ans)
    cout << lilAns << '\n';

#ifdef LOCAL
  cout << "\n\n\nExecution time: " << (clock() - stTime) * 1e3 / CLOCKS_PER_SEC
       << " ms" << endl;
#endif
  return 0;
}


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

using namespace std;

const int OO = 1e9;
const double EPS = 1e-9;

#define ndl cout << '\n'
#define sz(v) int(v.size())
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define present(a, x) (a.find(x) != a.end())
#ifdef LOCAL
#define db(...)                                                                \
  ({                                                                           \
    cout << "> Line " << __LINE__ << ": ";                                     \
    _db(#__VA_ARGS__, __VA_ARGS__);                                            \
  })
#else
#define db(...) true
#endif

template <class T> void _db(const char *dbStr, T e) {
  cout << dbStr << " = " << e << endl;
}
template <class T, class... L> void _db(const char *dbStr, T e, L... r) {
  while (*dbStr != ',')
    cout << *dbStr++;
  cout << " = " << e << ',';
  _db(dbStr + 1, r...);
}
template <class S, class T>
ostream &operator<<(ostream &o, const map<S, T> &v) {
  o << "[";
  int i = 0;
  for (const pair<S, T> &pr : v)
    o << (!i++ ? "" : ", ") << "{" << pr.fs << " : " << pr.sc << "}";
  return o << "]";
}
template <template <class, class...> class S, class T, class... L>
ostream &operator<<(ostream &o, const S<T, L...> &v) {
  o << "[";
  int i = 0;
  for (const auto &e : v)
    o << (!i++ ? "" : ", ") << e;
  return o << "]";
}
template <class S, class T>
ostream &operator<<(ostream &o, const pair<S, T> &pr) {
  return o << "(" << pr.fs << ", " << pr.sc << ")";
}
ostream &operator<<(ostream &o, const string &s) {
  for (const char &c : s)
    o << c;
  return o;
}

template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;
template <class T> using VVV = VV<V<T>>;
using ll = long long;
using pii = pair<int, int>;
using vi = V<int>;
using vii = V<pii>;
using vvi = VV<int>;
using mii = map<int, int>;
using umii = unordered_map<int, int>;
using si = set<int>;
using usi = unordered_set<int>;

int N, Q;
V<V<pair<int, pii>>> adj; // (v, (c, d))
vi D, E, W;
V<V<pair<int, pair<int, pii>>>> nodeQuery; // (ID, (c, (y, coef.)))
vi ans;

#define LOG_TWO_N 25

struct SparseTable {
  vi A;
  vvi SpT;
  vvi mnIdx;
  SparseTable(const vi &_A) {
    A = _A;
    int n = A.size();
    SpT.assign(n, vi(LOG_TWO_N));
    mnIdx.assign(n, vi(LOG_TWO_N));
    for (int i = 0; i < n; i++)
      SpT[i][0] = i, mnIdx[i][0] = i;
    for (int j = 1; (1 << j) <= n; ++j)
      for (int i = 0; i + (1 << j) - 1 < n; ++i)
        if (A[SpT[i][j - 1]] < A[SpT[i + (1 << (j - 1))][j - 1]])
          SpT[i][j] = SpT[i][j - 1], mnIdx[i][j] = mnIdx[i][j - 1];
        else
          SpT[i][j] = SpT[i + (1 << (j - 1))][j - 1],
          mnIdx[i][j] = mnIdx[i + (1 << (j - 1))][j - 1];
  }
  SparseTable() {}
  int query(int i, int j) {
    int k = floor(log2(j - i + 1));
    if (A[SpT[i][k]] <= A[SpT[j - (1 << k) + 1][k]])
      return SpT[i][k];
    else
      return SpT[j - (1 << k) + 1][k];
  }
  int queryIdx(int i, int j) {
    int k = floor(log2(j - i + 1));
    if (A[SpT[i][k]] <= A[SpT[j - (1 << k) + 1][k]])
      return mnIdx[i][k];
    else
      return mnIdx[j - (1 << k) + 1][k];
  }
};

struct LCA {
  int n, idx;
  vi dep, seq, fsOcc;
  SparseTable RMQ;
  void dfs(int node, int depth, int parent) {
    fsOcc[node] = idx;
    seq[idx] = node;
    dep[idx++] = depth;
    for (auto &pr : adj[node])
      if (pr.fs != parent) {
        dfs(pr.fs, depth + 1, node);
        seq[idx] = node;
        dep[idx++] = depth;
      }
  }
  LCA(int _n, int root) {
    n = _n + 1;
    dep.assign(2 * n, 0);
    seq.assign(2 * n, 0);
    fsOcc.assign(n, 0);
    idx = 0;
    dfs(root, 0, -1);
    RMQ = SparseTable(dep);
  }
  int query(int u, int v) {
    if (fsOcc[u] > fsOcc[v])
      swap(u, v);
    return seq[RMQ.query(fsOcc[u], fsOcc[v])];
  }
};

void dfs(int node, int par, int dist) {
  db(node, E, W);
  D[node] = dist;
  for (auto &data : nodeQuery[node])
    ans[data.fs] += data.sc.sc.sc *
                    (D[node] + data.sc.sc.fs * E[data.sc.fs] - W[data.sc.fs]);

  for (auto &pr : adj[node])
    if (pr.fs != par) {
      ++E[pr.sc.fs];
      W[pr.sc.fs] += pr.sc.sc;
      dfs(pr.fs, node, dist + pr.sc.sc);
      --E[pr.sc.fs];
      W[pr.sc.fs] -= pr.sc.sc;
    }
}

int main() {
#ifdef LOCAL
  auto stTime = clock();
  //	freopen("in.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cout.precision(10);
  cin.tie(0);

  cin >> N >> Q;
  adj.assign(N + 1, V<pair<int, pii>>());
  nodeQuery.assign(N + 1, V<pair<int, pair<int, pii>>>());
  D.assign(N + 1, 0);
  E.assign(N, 0);
  W.assign(N, 0);
  int u, v, c, d;
  for (int i = 0; i < N - 1; ++i) {
    cin >> u >> v >> c >> d;
    adj[u].pb(mp(v, mp(c, d)));
    adj[v].pb(mp(u, mp(c, d)));
  }
  LCA lca(N, 1);
  ans.assign(Q, 0);
  int x, y;
  for (int i = 0; i < Q; ++i) {
    cin >> x >> y >> u >> v;
    nodeQuery[u].pb(mp(i, mp(x, mp(y, 1))));
    nodeQuery[v].pb(mp(i, mp(x, mp(y, 1))));
    nodeQuery[lca.query(u, v)].pb(mp(i, mp(x, mp(y, -2))));
  }
  dfs(1, -1, 0);
  db(D);
  for (auto &lilAns : ans)
    cout << lilAns << '\n';

#ifdef LOCAL
  cout << "\n\n\nExecution time: " << (clock() - stTime) * 1e3 / CLOCKS_PER_SEC
       << " ms" << endl;
#endif
  return 0;
}