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

#include <bits/stdc++.h>
#define N (1 << 17)
#define int long long
using namespace std;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }

class HLD {
public:
  int V;                 //???????????°
  int root;              //??????????????????
  vector<vector<int>> G; // Grapth
  vector<int> par;       // parent: par[??????????????????]
  vector<int> Hedge;  //???????????????????????????Heavy Child???????????????:
                      //Hedge[??????????????????]
  vector<int> number; //???????????????????????????????????????????????????:
                      //number[??????????????????]->????????´??????????????????
  vector<int> id;     //??????????????´????????°???????????????????????????:
                      //id[????????´??????????????????]->??????????????????
  vector<int> group;  //???????????????????±?????????°???????????????:
                      //group[??????????????????]
  vector<int>
      depth; //?????????????????????????????±???: depth[??????????????????]
  bool ok;   // build()???????????§?????????

  HLD() { root = V = -1; }
  HLD(int V, int root = 0)
      : V(V++), root(), G(V), par(V, -1), Hedge(V, -1), number(V, -1),
        id(V, -1), group(V, -1), depth(V, 0), ok(0) {}

  void add_edge(int a, int b) {
    assert(a < V && b < V);
    G[a].push_back(b);
    G[b].push_back(a);
  }

  void build() {
    ok = 1;
    HLD(V);
    buildWeight(); // weight and parent
    int num = 0;
    numbering(num);
    buildDepthAndGroup();
  }

  int buildWeight(int pos = -1, int pre = -1) {
    if (pos == -1)
      pos = root;
    par[pos] = pre;

    int mx = -1, weight = 1;
    for (int nx : G[pos]) {
      if (nx == pre)
        continue;
      int cweight = buildWeight(nx, pos);
      weight += cweight;
      if (mx < cweight)
        Hedge[pos] = nx, mx = cweight;
    }
    return weight;
  }

  void buildDepthAndGroup(int pos = -1, int pre = -1, int dep = 0, int g = 0) {
    if (pos == -1)
      pos = root;
    depth[pos] = dep;
    group[pos] = g;
    for (int nx : G[pos])
      if (nx != pre)
        buildDepthAndGroup(nx, pos, dep + 1, Hedge[pos] == nx ? g : nx);
  }

  void numbering(int &cnt, int pos = -1) {
    if (pos == -1)
      pos = root;
    number[pos] = cnt++;
    id[number[pos]] = pos;
    if (Hedge[pos] >= 0)
      numbering(cnt, Hedge[pos]);
    for (int nx : G[pos])
      if (nx != par[pos] && nx != Hedge[pos])
        numbering(cnt, nx);
  }

  typedef pair<int, int> P;
  vector<P> paths;
  void buildPaths(int u, int v, int init = 1) {
    if (init)
      paths.clear();
    assert(ok);
    int nu = number[u], nv = number[v];
    if (same(u, v)) {
      paths.push_back(P(min(nu, nv), max(nu, nv)));
      return;
    }
    if (depth[group[u]] < depth[group[v]])
      swap(u, v); // ??±???????????????????????????????????????
    buildPaths(par[group[u]], v, 0);
    paths.push_back(P(number[group[u]], number[u]));
  }

  // same(???????????????????????????????????????)
  bool same(int a, int b) { return group[a] == group[b]; }
};

typedef pair<int, int> P;
class Stree {
public:
  struct data {
    int sum, l, r;
  };
  HLD H;
  int K;
  int n;
  bool ok;
  unordered_map<int, unordered_map<int, int>> G;
  vector<data> dat;
  unordered_map<int, int> x;
  //?????????
  Stree() {
    ok = 0;
    K = -1;
    n = N;
    dat.resize(2 * n - 1, (data){0, -1, -1});
  }

  void pr(data a) {
    cout << "(" << a.sum << " " << a.l << " " << a.r << ")" << endl;
  }
  bool same(int a, int b) { return H.same(a, b); }

  void build(HLD &H) {
    this->H = H;
    ok = 1;
    assert(K > 0);
    for (int i = 0; i < n - 1; i++) {
      if (!same(H.id[i], H.id[i + 1]))
        continue;
      dat[i + n - 1].r = H.id[i + 1];
      dat[i + 1 + n - 1].l = H.id[i];
    }
    for (int i = 0; i < n; i++)
      add(i, 0);
  }

  data merge(data a, data b, int flg = 0) {
    if (flg)
      cout << "a=(" << a.sum << "," << a.l << "," << a.r << ")";
    if (flg)
      cout << " b=(" << b.sum << "," << b.l << "," << b.r << ")" << endl;
    int l = b.l, r = a.r;
    if (a.sum == -1)
      return b;
    if (b.sum == -1)
      return a;
    if (!same(r, l))
      return a;
    int sum = a.sum + b.sum;
    int d = G[r][l] + x[r] + x[l];
    if (d % K)
      sum += d;
    if (flg)
      cout << "res=(" << sum << "," << a.l << "," << b.r << ")" << endl;
    return (data){sum, a.l, b.r};
  }

  void add(int k, int a) { // k???????????????a?????????
    assert(ok);
    x[k] += a;
    k = H.number[k];
    k += n - 1;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = merge(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  //[a,b)???????°????????±??????? query(a,b,0,0,n)
  data sum(int a, int b, int k = 0, int l = 0, int r = N) {
    if (r <= a || b <= l)
      return (data){-1, -1, -1};
    if (a <= l && r <= b)
      return dat[k];

    data vl = sum(a, b, k * 2 + 1, l, (l + r) / 2);
    data vr = sum(a, b, k * 2 + 2, (l + r) / 2, r);

    return merge(vl, vr, 0);
  }

  int sum(int a, int b, HLD &H) {
    assert(ok);
    int res = 0;
    // for(int i=0;i<10;i++)cout<<H.number[i]<<" ";cout<<endl;
    // for(int i=0;i<10;i++)cout<<H.group[i]<<" ";cout<<endl;

    H.buildPaths(a, b);
    set<int> group;
    for (P p : H.paths) {
      // cout<<"path="<<p.first<<" "<<p.second;
      // cout<<" res="<<sum(p.first,p.second+1).sum<<endl;
      res += sum(p.first, p.second + 1).sum;
      group.insert(H.group[H.id[p.first]]);
    }

    for (P p : H.paths) {
      int g = H.group[H.id[p.first]];
      int par = H.par[g];
      if (par == -1)
        continue;
      // cout<<"g:par "<<g<<" "<<par<<endl;
      // if(group.count(H.group[par])) cout<<(G[g][par])<<" "<<x[g]<<"
      // "<<x[par]<<endl;
      if (group.count(H.group[par]))
        res += (G[g][par] + x[g] + x[par]) % K ? G[g][par] + x[g] + x[par] : 0;
    }

    return res;
  }
};

signed main() {
  int n, K;
  cin >> n >> K;
  Stree T;
  T.K = K;
  HLD H(T.n);

  for (int i = 0; i < n - 1; i++) {
    int a, b, c;
    scanf("%lld %lld %lld", &a, &b, &c);
    H.add_edge(a, b);
    T.G[a][b] = c;
    T.G[b][a] = c;
  }

  int q;
  cin >> q;
  H.build();

  T.build(H);
  while (q--) {
    char str[10];
    int a, b;
    scanf("%s %lld %lld", str, &a, &b);
    // cout<<str<<" "<<a<<" "<<b<<endl;
    if (str[0] == 'a')
      T.add(a, b);
    if (str[0] == 's')
      printf("%lld\\n", T.sum(a, b, H));
  }

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define N (1 << 17)
#define int long long
using namespace std;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }

class HLD {
public:
  int V;                 //???????????°
  int root;              //??????????????????
  vector<vector<int>> G; // Grapth
  vector<int> par;       // parent: par[??????????????????]
  vector<int> Hedge;  //???????????????????????????Heavy Child???????????????:
                      //Hedge[??????????????????]
  vector<int> number; //???????????????????????????????????????????????????:
                      //number[??????????????????]->????????´??????????????????
  vector<int> id;     //??????????????´????????°???????????????????????????:
                      //id[????????´??????????????????]->??????????????????
  vector<int> group;  //???????????????????±?????????°???????????????:
                      //group[??????????????????]
  vector<int>
      depth; //?????????????????????????????±???: depth[??????????????????]
  bool ok;   // build()???????????§?????????

  HLD() { root = V = -1; }
  HLD(int V, int root = 0)
      : V(V++), root(), G(V), par(V, -1), Hedge(V, -1), number(V, -1),
        id(V, -1), group(V, -1), depth(V, 0), ok(0) {}

  void add_edge(int a, int b) {
    assert(a < V && b < V);
    G[a].push_back(b);
    G[b].push_back(a);
  }

  void build() {
    ok = 1;
    HLD(V);
    buildWeight(); // weight and parent
    int num = 0;
    numbering(num);
    buildDepthAndGroup();
  }

  int buildWeight(int pos = -1, int pre = -1) {
    if (pos == -1)
      pos = root;
    par[pos] = pre;

    int mx = -1, weight = 1;
    for (int nx : G[pos]) {
      if (nx == pre)
        continue;
      int cweight = buildWeight(nx, pos);
      weight += cweight;
      if (mx < cweight)
        Hedge[pos] = nx, mx = cweight;
    }
    return weight;
  }

  void buildDepthAndGroup(int pos = -1, int pre = -1, int dep = 0, int g = 0) {
    if (pos == -1)
      pos = root;
    depth[pos] = dep;
    group[pos] = g;
    for (int nx : G[pos])
      if (nx != pre)
        buildDepthAndGroup(nx, pos, dep + 1, Hedge[pos] == nx ? g : nx);
  }

  void numbering(int &cnt, int pos = -1) {
    if (pos == -1)
      pos = root;
    number[pos] = cnt++;
    id[number[pos]] = pos;
    if (Hedge[pos] >= 0)
      numbering(cnt, Hedge[pos]);
    for (int nx : G[pos])
      if (nx != par[pos] && nx != Hedge[pos])
        numbering(cnt, nx);
  }

  typedef pair<int, int> P;
  vector<P> paths;
  void buildPaths(int u, int v, int init = 1) {
    if (init)
      paths.clear();
    assert(ok);
    int nu = number[u], nv = number[v];
    if (same(u, v)) {
      paths.push_back(P(min(nu, nv), max(nu, nv)));
      return;
    }
    if (depth[group[u]] < depth[group[v]])
      swap(u, v); // ??±???????????????????????????????????????
    buildPaths(par[group[u]], v, 0);
    paths.push_back(P(number[group[u]], number[u]));
  }

  // same(???????????????????????????????????????)
  bool same(int a, int b) { return group[a] == group[b]; }
};

typedef pair<int, int> P;
class Stree {
public:
  struct data {
    int sum, l, r;
  };
  HLD H;
  int K;
  int n;
  bool ok;
  unordered_map<int, unordered_map<int, int>> G;
  vector<data> dat;
  unordered_map<int, int> x;
  //?????????
  Stree() {
    ok = 0;
    K = -1;
    n = N;
    dat.resize(2 * n - 1, (data){0, -1, -1});
  }

  void pr(data a) {
    cout << "(" << a.sum << " " << a.l << " " << a.r << ")" << endl;
  }
  bool same(int a, int b) { return H.same(a, b); }

  void build(HLD &H) {
    this->H = H;
    ok = 1;
    assert(K > 0);
    for (int i = 0; i < n - 1; i++) {
      if (!same(H.id[i], H.id[i + 1]))
        continue;
      dat[i + n - 1].r = H.id[i + 1];
      dat[i + 1 + n - 1].l = H.id[i];
    }
    for (int i = 0; i < n; i++)
      add(i, 0);
  }

  data merge(data a, data b, int flg = 0) {
    if (flg)
      cout << "a=(" << a.sum << "," << a.l << "," << a.r << ")";
    if (flg)
      cout << " b=(" << b.sum << "," << b.l << "," << b.r << ")" << endl;
    int l = b.l, r = a.r;
    if (a.sum == -1)
      return b;
    if (b.sum == -1)
      return a;
    if (!same(r, l))
      return a;
    int sum = a.sum + b.sum;
    int d = G[r][l] + x[r] + x[l];
    if (d % K)
      sum += d;
    if (flg)
      cout << "res=(" << sum << "," << a.l << "," << b.r << ")" << endl;
    return (data){sum, a.l, b.r};
  }

  void add(int k, int a) { // k???????????????a?????????
    assert(ok);
    x[k] += a;
    k = H.number[k];
    k += n - 1;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = merge(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  //[a,b)???????°????????±??????? query(a,b,0,0,n)
  data sum(int a, int b, int k = 0, int l = 0, int r = N) {
    if (r <= a || b <= l)
      return (data){-1, -1, -1};
    if (a <= l && r <= b)
      return dat[k];

    data vl = sum(a, b, k * 2 + 1, l, (l + r) / 2);
    data vr = sum(a, b, k * 2 + 2, (l + r) / 2, r);

    return merge(vl, vr, 0);
  }

  int sum(int a, int b, HLD &H) {
    assert(ok);
    int res = 0;
    // for(int i=0;i<10;i++)cout<<H.number[i]<<" ";cout<<endl;
    // for(int i=0;i<10;i++)cout<<H.group[i]<<" ";cout<<endl;

    H.buildPaths(a, b);
    set<int> group;
    for (P p : H.paths) {
      // cout<<"path="<<p.first<<" "<<p.second;
      // cout<<" res="<<sum(p.first,p.second+1).sum<<endl;
      res += sum(p.first, p.second + 1).sum;
      group.insert(H.group[H.id[p.first]]);
    }

    for (P p : H.paths) {
      int g = H.group[H.id[p.first]];
      int par = H.par[g];
      if (par == -1)
        continue;
      // cout<<"g:par "<<g<<" "<<par<<endl;
      // if(group.count(H.group[par])) cout<<(G[g][par])<<" "<<x[g]<<"
      // "<<x[par]<<endl;
      if (group.count(H.group[par]))
        res += (G[g][par] + x[g] + x[par]) % K ? G[g][par] + x[g] + x[par] : 0;
    }

    return res;
  }
};

signed main() {
  int n, K;
  cin >> n >> K;
  Stree T;
  T.K = K;
  HLD H(T.n);

  for (int i = 0; i < n - 1; i++) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    H.add_edge(a, b);
    T.G[a][b] = c;
    T.G[b][a] = c;
  }

  int q;
  cin >> q;
  H.build();

  T.build(H);
  while (q--) {
    char str[10];
    int a, b;
    scanf("%s %d %d", str, &a, &b);
    // cout<<str<<" "<<a<<" "<<b<<endl;
    if (str[0] == 'a')
      T.add(a, b);
    if (str[0] == 's')
      printf("%d\\n", T.sum(a, b, H));
  }

  return 0;
}