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

#include <bits/stdc++.h>
using namespace std;
#define MAX 150005
typedef long long ll;
bool flg = false;

int n, q, a, b, c;

vector<int> G[MAX];
int sz[MAX], cd[MAX], mv[MAX], pr[MAX], de[MAX];

vector<int> H;
int hl[MAX], hr[MAX];

// calc hl[] hr[] mv[]
void dfsB(int pos) {
  hl[pos] = H.size();
  H.push_back(pos);
  if (cd[pos] != -1) {
    mv[cd[pos]] = mv[pos];
    dfsB(cd[pos]);
  }

  for (int i = 0; i < (int)G[pos].size(); i++) {
    int to = G[pos][i];
    if (to == pr[pos] || to == cd[pos])
      continue;
    dfsB(to);
  }
  hr[pos] = H.size();
}

// calc cd[] pr[] de[] , init mv[]
void dfsA(int pos) {
  if (de[pos] >= 100000) {
    flg = true;
  }
  cd[pos] = -1;
  sz[pos] = 1;
  mv[pos] = pos;
  for (int i = 0; i < (int)G[pos].size(); i++) {
    int to = G[pos][i];
    if (to == pr[pos])
      continue;
    pr[to] = pos;
    de[to] = de[pos] + 1;
    dfsA(to);
    sz[pos] += sz[to];
    if (cd[pos] == -1 || sz[cd[pos]] < sz[to])
      cd[pos] = to;
  }
}

void init() {
  H.clear();
  for (int i = 0; i < n; i++) {
    G[i].clear();
  }
}

char ch(int x) { return 'A' + x; }

struct segtree {
  int n;
  vector<ll> A, B;
  void init(int N) {
    A.clear(), B.clear();
    for (n = 1; n < N; n *= 2)
      ;
    A.resize(n + n), B.resize(n + n);
  }
  void add(int a, int b, int x, int k, int l, int r) {
    if (b <= l || r <= a)
      return;
    if (a <= l && r <= b) {
      A[k] += x;
      return;
    }
    B[k] += (min(b, r) - max(a, l)) * x;
    int m = (l + r) / 2;
    add(a, b, x, k * 2 + 1, l, m);
    add(a, b, x, k * 2 + 2, m, r);
  }
  void add(int a, int b, int x) { add(a, b, x, 0, 0, n); }
  ll sum(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return 0;
    if (a <= l && r <= b)
      return A[k] * (r - l) + B[k];
    int m = (l + r) / 2;
    return sum(a, b, k * 2 + 1, l, m) + sum(a, b, k * 2 + 2, m, r) +
           A[k] * (min(b, r) - max(a, l));
  }
  ll sum(int a, int b) { return sum(a, b, 0, 0, n); }
};

segtree t;

int stacka[MAX], size;
int stackb[MAX];

int main() {
  while (scanf("%d %d", &n, &q) == 2) {
    t.init(n);
    init();
    for (int i = 0; i < n - 1; i++) {
      scanf("%d %d", &a, &b);
      G[a].push_back(b);
      G[b].push_back(a);
    }

    for (int i = 0; i < n; i++)
      sort(G[i].begin(), G[i].end());

    pr[0] = -1;
    de[0] = 0;
    // dfsA(0); runtime error
    // dfsB(0);
    size = 1;
    stacka[0] = 0;
    stackb[0] = 0;
    int pos, cnt;
    while (size > 0) {
      size--;
      pos = stacka[size];
      cnt = stackb[size];

      if (cnt == (int)G[pos].size()) {
        if (pr[pos] != -1) {
          sz[pr[pos]] += sz[pos];
        }
        continue;
      }

      stacka[size] = pos;
      stackb[size] = cnt + 1;
      size++;

      if (G[pos][cnt] != pr[pos]) {
        pr[G[pos][cnt]] = pos;
        de[G[pos][cnt]] = de[pos] + 1;
        stacka[size] = G[pos][cnt];
        stackb[size] = 0;
        size++;
      }
    }

    for (int pos = 0; pos < n; pos++) {
      cd[pos] = -1;
      mv[pos] = pos;
      for (int j = 0; j < (int)G[pos].size(); j++) {
        int to = G[pos][j];
        if (to == pr[pos])
          continue;
        if (cd[pos] == -1 || sz[cd[pos]] < sz[to])
          cd[pos] = to;
      }
    }
    dfsB(0);
    /*
    for(int i=0;i<n;i++){
      cout<< ch(i) <<" pr = "<<ch(pr[i])<<" , ";
      cout<<" sz = "<<ch(sz[i])<<" , ";
      cout<<" de = "<<ch(de[i])<<" , ";
      cout<<endl;
    }
    */
    while (q--) {
      scanf("%d %d %d", &a, &b, &c);

      if (a == 1) {
        t.add(hl[b], hr[b], c);
        t.add(hl[b], hl[b] + 1, -c);
      } else {
        ll ans = 0;
        while (mv[b] != mv[c]) {
          if (de[mv[b]] < de[mv[c]])
            swap(b, c);
          ans += t.sum(hl[mv[b]], hl[b] + 1);
          b = pr[mv[b]];
        }
        if (hl[b] > hl[c])
          swap(b, c);
        ans += t.sum(hl[b] + 1, hl[c] + 1);
        printf("%lld\\n", ans);
      }
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define MAX 150005
typedef long long ll;
bool flg = false;

int n, q, a, b, c;

vector<int> G[MAX];
int sz[MAX], cd[MAX], mv[MAX], pr[MAX], de[MAX];

vector<int> H;
int hl[MAX], hr[MAX];

// calc hl[] hr[] mv[]
void dfsB(int pos) {
  hl[pos] = H.size();
  H.push_back(pos);
  if (cd[pos] != -1) {
    mv[cd[pos]] = mv[pos];
    dfsB(cd[pos]);
  }

  for (int i = 0; i < (int)G[pos].size(); i++) {
    int to = G[pos][i];
    if (to == pr[pos] || to == cd[pos])
      continue;
    dfsB(to);
  }
  hr[pos] = H.size();
}

// calc cd[] pr[] de[] , init mv[]
void dfsA(int pos) {
  if (de[pos] >= 100000) {
    flg = true;
  }
  cd[pos] = -1;
  sz[pos] = 1;
  mv[pos] = pos;
  for (int i = 0; i < (int)G[pos].size(); i++) {
    int to = G[pos][i];
    if (to == pr[pos])
      continue;
    pr[to] = pos;
    de[to] = de[pos] + 1;
    dfsA(to);
    sz[pos] += sz[to];
    if (cd[pos] == -1 || sz[cd[pos]] < sz[to])
      cd[pos] = to;
  }
}

void init() {
  H.clear();
  for (int i = 0; i < n; i++) {
    G[i].clear();
  }
}

char ch(int x) { return 'A' + x; }

struct segtree {
  int n;
  vector<ll> A, B;
  void init(int N) {
    A.clear(), B.clear();
    for (n = 1; n < N; n *= 2)
      ;
    A.resize(n + n), B.resize(n + n);
  }
  void add(int a, int b, int x, int k, int l, int r) {
    if (b <= l || r <= a)
      return;
    if (a <= l && r <= b) {
      A[k] += x;
      return;
    }
    B[k] += (min(b, r) - max(a, l)) * x;
    int m = (l + r) / 2;
    add(a, b, x, k * 2 + 1, l, m);
    add(a, b, x, k * 2 + 2, m, r);
  }
  void add(int a, int b, int x) { add(a, b, x, 0, 0, n); }
  ll sum(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return 0;
    if (a <= l && r <= b)
      return A[k] * (r - l) + B[k];
    int m = (l + r) / 2;
    return sum(a, b, k * 2 + 1, l, m) + sum(a, b, k * 2 + 2, m, r) +
           A[k] * (min(b, r) - max(a, l));
  }
  ll sum(int a, int b) { return sum(a, b, 0, 0, n); }
};

segtree t;

int main() {
  while (scanf("%d %d", &n, &q) == 2) {
    t.init(n);
    init();
    for (int i = 0; i < n - 1; i++) {
      scanf("%d %d", &a, &b);
      G[a].push_back(b);
      G[b].push_back(a);
    }

    for (int i = 0; i < n; i++)
      sort(G[i].begin(), G[i].end());

    pr[0] = -1;
    de[0] = 0;
    dfsA(0);

    if (flg) {

      while (1) {
      }
    }

    dfsB(0);

    while (q--) {
      scanf("%d %d %d", &a, &b, &c);
      if (a == 1) {
        t.add(hl[b], hr[b], c);
        t.add(hl[b], hl[b] + 1, -c);
      } else {
        ll ans = 0;
        while (mv[b] != mv[c]) {
          if (de[mv[b]] < de[mv[c]])
            swap(b, c);
          ans += t.sum(hl[mv[b]], hl[b] + 1);
          b = pr[mv[b]];
        }
        if (hl[b] > hl[c])
          swap(b, c);
        ans += t.sum(hl[b] + 1, hl[c] + 1);
        printf("%lld\\n", ans);
      }
    }
  }
  return 0;
}