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

#include <bits/stdc++.h>
using namespace std;
using Int = long long;

struct HLDecomposition {
  int n, pos;
  vector<vector<int>> G;
  vector<int> vid, head, sub, hvy, par, dep, inv, type;

  HLDecomposition() {}
  HLDecomposition(int sz)
      : n(sz), pos(0), G(n), vid(n, -1), head(n), sub(n, 1), hvy(n, -1), par(n),
        dep(n), inv(n), type(n) {}

  void add_edge(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
  }

  void build(vector<int> rs = {0}) {
    int c = 0;
    for (int r : rs) {
      dfs(r);
      bfs(r, c++);
    }
  }

  void dfs(int rt) {
    using T = pair<int, int>;
    stack<T> st;
    par[rt] = -1;
    dep[rt] = 0;
    st.emplace(rt, 0);
    while (!st.empty()) {
      int v = st.top().first;
      int &i = st.top().second;
      if (i < (int)G[v].size()) {
        int u = G[v][i++];
        if (u == par[v])
          continue;
        par[u] = v;
        dep[u] = dep[v] + 1;
        st.emplace(u, 0);
      } else {
        st.pop();
        int res = 0;
        for (int u : G[v]) {
          if (u == par[v])
            continue;
          sub[v] += sub[u];
          if (res < sub[u])
            res = sub[u], hvy[v] = u;
        }
      }
    }
  }

  void bfs(int r, int c) {
    int &k = pos;
    queue<int> q({r});
    while (!q.empty()) {
      int h = q.front();
      q.pop();
      for (int i = h; i != -1; i = hvy[i]) {
        type[i] = c;
        vid[i] = k++;
        inv[vid[i]] = i;
        head[i] = h;
        for (int j : G[i])
          if (j != par[i] && j != hvy[i])
            q.push(j);
      }
    }
  }

  // for_each(vertex)
  // [l,r] <- attention!!
  void for_each(int u, int v, const function<void(int, int)> &f) {
    while (1) {
      if (vid[u] > vid[v])
        swap(u, v);
      f(max(vid[head[v]], vid[u]), vid[v]);
      if (head[u] != head[v])
        v = par[head[v]];
      else
        break;
    }
  }

  // for_each(edge)
  // [l,r] <- attention!!
  void for_each_edge(int u, int v, const function<void(int, int)> &f) {
    while (1) {
      if (vid[u] > vid[v])
        swap(u, v);
      if (head[u] != head[v]) {
        f(vid[head[v]], vid[v]);
        v = par[head[v]];
      } else {
        if (u != v)
          f(vid[u] + 1, vid[v]);
        break;
      }
    }
  }

  int lca(int u, int v) {
    while (1) {
      if (vid[u] > vid[v])
        swap(u, v);
      if (head[u] == head[v])
        return u;
      v = par[head[v]];
    }
  }

  int distance(int u, int v) { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; }
};

template <typename T, typename E> struct SegmentTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  int n;
  F f;
  G g;
  T d1;
  E d0;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(int n_, F f, G g, T d1, vector<T> v = vector<T>())
      : f(f), g(g), d1(d1) {
    init(n_);
    if (n_ == (int)v.size())
      build(n_, v);
  }
  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.clear();
    dat.resize(2 * n - 1, d1);
  }
  void build(int n_, vector<T> v) {
    for (int i = 0; i < n_; i++)
      dat[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  void update(int k, E a) {
    k += n - 1;
    dat[k] = g(dat[k], a);
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  inline T query(int a, int b) {
    T vl = d1, vr = d1;
    for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = f(vl, dat[(l++) - 1]);
      if (r & 1)
        vr = f(dat[(--r) - 1], vr);
    }
    return f(vl, vr);
  }
};

signed main() {
  Int n, k;
  cin >> n >> k;

  HLDecomposition hld(n);
  vector<map<Int, Int>> m(n);

  for (Int i = 0; i < n - 1; i++) {
    Int a, b, c;
    cin >> a >> b >> c;
    hld.add_edge(a, b);
    m[a][b] = m[b][a] = c;
  }

  hld.build();
  using T = tuple<Int, Int, Int>;

  vector<Int> w(n, 0);
  auto mget = [&](Int a, Int b) {
    Int res = w[a] + w[b] + m[a][b];
    return (res % k == 0) ? 0 : res;
  };

  auto f = [&](T a, T b) {
    if (a > b)
      swap(a, b);
    Int al, ar, av;
    tie(al, ar, av) = a;
    Int bl, br, bv;
    tie(bl, br, bv) = b;
    if (al < 0 || ar < 0)
      return b;
    if (m[al].count(bl) || m[al].count(br))
      swap(al, ar);
    if (m[ar].count(br))
      swap(bl, br);
    if (!m[ar].count(bl))
      return T(-1, -1, -1);
    return T(al, br, av + bv + mget(ar, bl));
  };

  auto g = [](T a, Int b) { return T(b, b, 0); };

  SegmentTree<T, Int> seg(n, f, g, T(-1, -1, 0));

  for (Int i = 0; i < n; i++)
    seg.update(i, hld.inv[i]);

  Int q;
  cin >> q;
  while (q--) {
    string op;
    cin >> op;
    if (op == "add") {
      Int x, d;
      cin >> x >> d;
      w[x] += d;
      seg.update(hld.vid[x], x);
    }
    if (op == "send") {
      Int s, t;
      cin >> s >> t;
      vector<T> v;
      auto merge = [&](T x) {
        for (Int i = 0; i < (Int)v.size(); i++) {
          T y = f(x, v[i]);
          if (~get<2>(y)) {
            v[i] = y;
            return;
          }
        }
        v.push_back(x);
      };

      hld.for_each(s, t, [&](Int l, Int r) { merge(seg.query(l, r + 1)); });

      while ((Int)v.size() > 1) {
        T x = v.back();
        v.pop_back();
        merge(x);
      }

      cout << (get<2>(v.front())) << endl;
    }
  }
  return 0;
}

Error: -6
47907da8-c4dc-4876-8142-de39505019b7.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p00362/C++/s881963130.cpp:194: main()::<lambda(T, T)>: Assertion `m[ar].count(bl)' failed.


Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using Int = long long;

struct HLDecomposition {
  int n, pos;
  vector<vector<int>> G;
  vector<int> vid, head, sub, hvy, par, dep, inv, type;

  HLDecomposition() {}
  HLDecomposition(int sz)
      : n(sz), pos(0), G(n), vid(n, -1), head(n), sub(n, 1), hvy(n, -1), par(n),
        dep(n), inv(n), type(n) {}

  void add_edge(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
  }

  void build(vector<int> rs = {0}) {
    int c = 0;
    for (int r : rs) {
      dfs(r);
      bfs(r, c++);
    }
  }

  void dfs(int rt) {
    using T = pair<int, int>;
    stack<T> st;
    par[rt] = -1;
    dep[rt] = 0;
    st.emplace(rt, 0);
    while (!st.empty()) {
      int v = st.top().first;
      int &i = st.top().second;
      if (i < (int)G[v].size()) {
        int u = G[v][i++];
        if (u == par[v])
          continue;
        par[u] = v;
        dep[u] = dep[v] + 1;
        st.emplace(u, 0);
      } else {
        st.pop();
        int res = 0;
        for (int u : G[v]) {
          if (u == par[v])
            continue;
          sub[v] += sub[u];
          if (res < sub[u])
            res = sub[u], hvy[v] = u;
        }
      }
    }
  }

  void bfs(int r, int c) {
    int &k = pos;
    queue<int> q({r});
    while (!q.empty()) {
      int h = q.front();
      q.pop();
      for (int i = h; i != -1; i = hvy[i]) {
        type[i] = c;
        vid[i] = k++;
        inv[vid[i]] = i;
        head[i] = h;
        for (int j : G[i])
          if (j != par[i] && j != hvy[i])
            q.push(j);
      }
    }
  }

  // for_each(vertex)
  // [l,r] <- attention!!
  void for_each(int u, int v, const function<void(int, int)> &f) {
    while (1) {
      if (vid[u] > vid[v])
        swap(u, v);
      f(max(vid[head[v]], vid[u]), vid[v]);
      if (head[u] != head[v])
        v = par[head[v]];
      else
        break;
    }
  }

  // for_each(edge)
  // [l,r] <- attention!!
  void for_each_edge(int u, int v, const function<void(int, int)> &f) {
    while (1) {
      if (vid[u] > vid[v])
        swap(u, v);
      if (head[u] != head[v]) {
        f(vid[head[v]], vid[v]);
        v = par[head[v]];
      } else {
        if (u != v)
          f(vid[u] + 1, vid[v]);
        break;
      }
    }
  }

  int lca(int u, int v) {
    while (1) {
      if (vid[u] > vid[v])
        swap(u, v);
      if (head[u] == head[v])
        return u;
      v = par[head[v]];
    }
  }

  int distance(int u, int v) { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; }
};

template <typename T, typename E> struct SegmentTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  int n;
  F f;
  G g;
  T d1;
  E d0;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(int n_, F f, G g, T d1, vector<T> v = vector<T>())
      : f(f), g(g), d1(d1) {
    init(n_);
    if (n_ == (int)v.size())
      build(n_, v);
  }
  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.clear();
    dat.resize(2 * n - 1, d1);
  }
  void build(int n_, vector<T> v) {
    for (int i = 0; i < n_; i++)
      dat[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  void update(int k, E a) {
    k += n - 1;
    dat[k] = g(dat[k], a);
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  inline T query(int a, int b) {
    T vl = d1, vr = d1;
    for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = f(vl, dat[(l++) - 1]);
      if (r & 1)
        vr = f(dat[(--r) - 1], vr);
    }
    return f(vl, vr);
  }
};

signed main() {
  Int n, k;
  cin >> n >> k;

  HLDecomposition hld(n);
  vector<map<Int, Int>> m(n);

  for (Int i = 0; i < n - 1; i++) {
    Int a, b, c;
    cin >> a >> b >> c;
    hld.add_edge(a, b);
    m[a][b] = m[b][a] = c;
  }

  hld.build();
  using T = tuple<Int, Int, Int>;

  vector<Int> w(n, 0);
  auto mget = [&](Int a, Int b) {
    if (!m[a].count(b))
      return 0LL;
    Int res = w[a] + w[b] + m[a][b];
    if (res % k)
      return res;
    return 0LL;
  };

  auto f = [&](T a, T b) {
    if (a > b)
      swap(a, b);
    Int al, ar, av;
    tie(al, ar, av) = a;
    Int bl, br, bv;
    tie(bl, br, bv) = b;
    if (al < 0 || ar < 0)
      return b;
    if (m[al].count(bl) || m[al].count(br))
      swap(al, ar);
    if (m[ar].count(br))
      swap(bl, br);
    assert(m[ar].count(bl));
    return T(al, br, av + bv + mget(ar, bl));
  };

  auto g = [](T a, Int b) { return T(b, b, 0); };

  SegmentTree<T, Int> seg(n, f, g, T(-1, -1, 0));

  for (Int i = 0; i < n; i++)
    seg.update(i, hld.inv[i]);

  Int q;
  cin >> q;
  while (q--) {
    string op;
    cin >> op;
    if (op == "add") {
      Int x, d;
      cin >> x >> d;
      w[x] += d;
      seg.update(hld.vid[x], x);
    }
    if (op == "send") {
      Int s, t;
      cin >> s >> t;
      vector<T> v;
      auto merge = [&](T x) {
        for (Int i = 0; i < (Int)v.size(); i++) {
          T y = f(x, v[i]);
          if (~get<0>(y)) {
            v[i] = y;
            return;
          }
        }
        v.push_back(x);
      };

      hld.for_each(s, t, [&](Int l, Int r) { merge(seg.query(l, r + 1)); });

      while ((Int)v.size() > 1) {
        T x = v.back();
        v.pop_back();
        merge(x);
      }

      cout << (get<2>(v.front())) << endl;
    }
  }
  return 0;
}