Problem p01771 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(a) (a).begin(), (a).end()
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;

inline int MSB(int x) { return x > 0 ? 31 - __builtin_clz(x) : -1; }

struct LCA {
  vector<vi> par;
  vi depth;
  int ln;

  LCA(void) {}
  LCA(const vector<vi> t, int root) {
    int n = t.size();
    ln = MSB(n) + 1;
    depth.resize(n);
    par.resize(ln, vi(n));

    stack<pair<int, int>> s;
    s.push(make_pair(root, -1));
    while (s.size()) {
      int v = s.top().first, p = s.top().second;
      s.pop();
      par[0][v] = p;
      depth[v] = ((p < 0) ? 0 : (depth[p] + 1));
      for (int u : t[v]) {
        if (u != p)
          s.push(make_pair(u, v));
      }
    }

    rep(k, ln - 1) rep(v, n) {
      if (par[k][v] < 0)
        par[k + 1][v] = -1;
      else
        par[k + 1][v] = par[k][par[k][v]];
    }
  }

  inline int lca(int u, int v) {
    if (depth[u] > depth[v])
      swap(u, v);
    rep(k, ln) {
      if ((depth[v] - depth[u]) >> k & 1)
        v = par[k][v];
    }
    if (u == v)
      return u;
    for (int k = ln - 1; k >= 0; k--) {
      if (par[k][u] != par[k][v]) {
        u = par[k][u];
        v = par[k][v];
      }
    }
    return par[0][u];
  }
  inline int dep(int v) { return depth[v]; }
};

// Segment Tree for Range Maximum Query
class SegmentTree {
  int n;
  vl all, part;

public:
  SegmentTree(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    all = part = vl(2 * n - 1, 0);
  }

  void range_add(int a, int b, ll v, int k = 0, int l = 0, int r = 0) {
    if (l >= r)
      r = n;
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      all[k] += v;
      return;
    }
    part[k] += v * (min(r, b) - max(l, a));
    range_add(a, b, v, 2 * k + 1, l, (l + r) / 2);
    range_add(a, b, v, 2 * k + 2, (l + r) / 2, r);
  }

  // return maximum value in [a,b). ( [l,r) is interval in which k is.)
  ll range_sum(int a, int b, int k = 0, int l = 0, int r = 0) {
    if (l >= r)
      r = n;
    if (r <= a || b <= l)
      return 0;
    if (a <= l && r <= b)
      return all[k] * (r - l) + part[k];
    ll vl = range_sum(a, b, 2 * k + 1, l, (l + r) / 2);
    ll vr = range_sum(a, b, 2 * k + 2, (l + r) / 2, r);
    return vl + vr + all[k] * (min(r, b) - max(l, a));
  }
};

ll cost(int x, vi &open, vi &pos_open, vi &pos_close, SegmentTree &st_open,
        SegmentTree &st_close) {
  int pos = open[x];
  int op = upper_bound(all(pos_open), pos) - pos_open.begin();
  int cp = upper_bound(all(pos_close), pos) - pos_close.begin();

  // cout << x << " " <<  op << " " << cp << endl;
  // cout << st_open.range_sum(0,op) << " " << st_close.range_sum(0,cp) <<
  // endl;;

  return st_open.range_sum(0, op) - st_close.range_sum(0, cp);
}

int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  vector<vi> tree(n);
  rep(i, n - 1) {
    int a, b;
    scanf("%d%d", &a, &b);
    tree[a].push_back(b);
  }
  /*
  rep(i,n){
    for(int u: tree[i])cout << u << " "; cout << endl;
  }
  */

  LCA lca(tree, 0);

  int azu = 0;
  vi open(n, -1), close(n, -1);
  stack<int> s;
  s.push(0);
  while (s.size()) {
    int v = s.top();
    s.pop();
    if (open[v] < 0) {
      open[v] = azu++;
      s.push(v);
      for (int u : tree[v])
        s.push(u);
    } else {
      close[v] = azu++;
    }
  }

  vi pos_open = open, pos_close = close;
  sort(all(pos_open));
  sort(all(pos_close));

  SegmentTree st_open(n), st_close(n);

  /*
  rep(i,tour.size())cout << tour[i] << " "; cout << endl;
  rep(i,n)cout << open[i] << " "; cout << endl;
  rep(i,n)cout << close[i] << " "; cout << endl;
  */

  rep(i, q) {
    int x, u, v;
    scanf("%d%d%d", &x, &u, &v);
    if (x == 0) {
      int w = lca.lca(u, v);
      // cout << w << endl;
      ll res = cost(u, open, pos_open, pos_close, st_open, st_close) +
               cost(v, open, pos_open, pos_close, st_open, st_close) -
               2 * cost(w, open, pos_open, pos_close, st_open, st_close);
      printf("%lld\\n", res);
    } else {
      int l = open[u], r = close[u];
      int olp = upper_bound(all(pos_open), l) - pos_open.begin();
      int orp = lower_bound(all(pos_open), r) - pos_open.begin();
      int clp = upper_bound(all(pos_close), l) - pos_close.begin();
      int crp = lower_bound(all(pos_close), r) - pos_close.begin();

      // cout << olp << " " << orp << " " << clp << " " << crp << endl;
      st_open.range_add(olp, orp, v);
      st_close.range_add(clp, crp, v);
    }
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(a) (a).begin(), (a).end()
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;

inline int MSB(int x) { return x > 0 ? 31 - __builtin_clz(x) : -1; }

struct LCA {
  vector<vi> par;
  vi depth;
  int ln;

  LCA(void) {}
  LCA(const vector<vi> t, int root) {
    int n = t.size();
    ln = MSB(n) + 1;
    depth.resize(n);
    par.resize(ln, vi(n));

    stack<pair<int, int>> s;
    s.push(make_pair(root, -1));
    while (s.size()) {
      int v = s.top().first, p = s.top().second;
      s.pop();
      par[0][v] = p;
      depth[v] = ((p < 0) ? 0 : (depth[p] + 1));
      for (int u : t[v]) {
        if (u != p)
          s.push(make_pair(u, v));
      }
    }

    rep(k, ln - 1) rep(v, n) {
      if (par[k][v] < 0)
        par[k + 1][v] = -1;
      else
        par[k + 1][v] = par[k][par[k][v]];
    }
  }

  inline int lca(int u, int v) {
    if (depth[u] > depth[v])
      swap(u, v);
    rep(k, ln) {
      if ((depth[v] - depth[u]) >> k & 1)
        v = par[k][v];
    }
    if (u == v)
      return u;
    for (int k = ln - 1; k >= 0; k--) {
      if (par[k][u] != par[k][v]) {
        u = par[k][u];
        v = par[k][v];
      }
    }
    return par[0][u];
  }
  inline int dep(int v) { return depth[v]; }
};

// Segment Tree for Range Maximum Query
class SegmentTree {
  int n;
  vl all, part;

public:
  SegmentTree(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    all = part = vl(2 * n - 1, 0);
  }

  void range_add(int a, int b, ll v, int k = 0, int l = 0, int r = 0) {
    if (l >= r)
      r = n;
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      all[k] += v;
      return;
    }
    part[k] += v * (min(r, b) - max(l, a));
    range_add(a, b, v, 2 * k + 1, l, (l + r) / 2);
    range_add(a, b, v, 2 * k + 2, (l + r) / 2, r);
  }

  // return maximum value in [a,b). ( [l,r) is interval in which k is.)
  ll range_sum(int a, int b, int k = 0, int l = 0, int r = 0) {
    if (l >= r)
      r = n;
    if (r <= a || b <= l)
      return 0;
    if (a <= l && r <= b)
      return all[k] * (r - l) + part[k];
    ll vl = range_sum(a, b, 2 * k + 1, l, (l + r) / 2);
    ll vr = range_sum(a, b, 2 * k + 2, (l + r) / 2, r);
    return vl + vr + all[k] * (min(r, b) - max(l, a));
  }
};

void dfs(int v, vector<vi> &tree, int &k, vi &tour) {
  tour[k++] = v;
  for (int u : tree[v]) {
    dfs(u, tree, k, tour);
  }
  tour[k++] = v;
}

ll cost(int x, vi &open, vi &pos_open, vi &pos_close, SegmentTree &st_open,
        SegmentTree &st_close) {
  int pos = open[x];
  int op = upper_bound(all(pos_open), pos) - pos_open.begin();
  int cp = upper_bound(all(pos_close), pos) - pos_close.begin();

  // cout << x << " " <<  op << " " << cp << endl;
  // cout << st_open.range_sum(0,op) << " " << st_close.range_sum(0,cp) <<
  // endl;;

  return st_open.range_sum(0, op) - st_close.range_sum(0, cp);
}

int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  vector<vi> tree(n);
  rep(i, n - 1) {
    int a, b;
    scanf("%d%d", &a, &b);
    tree[a].push_back(b);
  }
  /*
  rep(i,n){
    for(int u: tree[i])cout << u << " "; cout << endl;
  }
  */

  LCA lca(tree, 0);

  vi tour(2 * n);
  int azu = 0;
  dfs(0, tree, azu, tour);

  vi open(n, -1), close(n, -1);
  rep(i, 2 * n) {
    if (open[tour[i]] < 0)
      open[tour[i]] = i;
    else
      close[tour[i]] = i;
  }

  vi pos_open = open, pos_close = close;
  sort(all(pos_open));
  sort(all(pos_close));

  SegmentTree st_open(n), st_close(n);

  /*
  rep(i,tour.size())cout << tour[i] << " "; cout << endl;
  rep(i,n)cout << open[i] << " "; cout << endl;
  rep(i,n)cout << close[i] << " "; cout << endl;
  */

  rep(i, q) {
    int x, u, v;
    scanf("%d%d%d", &x, &u, &v);
    if (x == 0) {
      int w = lca.lca(u, v);
      // cout << w << endl;
      ll res = cost(u, open, pos_open, pos_close, st_open, st_close) +
               cost(v, open, pos_open, pos_close, st_open, st_close) -
               2 * cost(w, open, pos_open, pos_close, st_open, st_close);
      printf("%lld\\n", res);
    } else {
      int l = open[u], r = close[u];
      int olp = upper_bound(all(pos_open), l) - pos_open.begin();
      int orp = lower_bound(all(pos_open), r) - pos_open.begin();
      int clp = upper_bound(all(pos_close), l) - pos_close.begin();
      int crp = lower_bound(all(pos_close), r) - pos_close.begin();

      // cout << olp << " " << orp << " " << clp << " " << crp << endl;
      st_open.range_add(olp, orp, v);
      st_close.range_add(clp, crp, v);
    }
  }
}