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

#include <stdio.h>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long Int;
#define NUM (400000)

struct BIT {
  static const int N = NUM;
  Int x[N];
  void add(int k, Int a) {
    for (; k < N; k |= k + 1)
      x[k] += a;
  }
  Int sum(int k) {
    Int s = 0;
    for (; k >= 0; k = (k & (k + 1)) - 1)
      s += x[k];
    return s;
  }
} A, B;

int n, Q;
vector<int> g[NUM], p[NUM];
int _i, x[NUM], y[NUM], h[NUM], r[NUM], sz[NUM];

/*
void rec(int at, int pre) {
    if (pre != -1) {
        p[at].push_back(pre);
        for (int ch = 1, k = 0; ch*2 <= h[at]; ch *= 2, k++) {
            p[at].push_back(p[p[at][k]][k]);
        }
    }
    x[at] = _i++;
    rep (i, g[at].size()) {
        h[g[at][i]] = h[at] + 1;
        rec(g[at][i], at);
    }
    y[at] = _i;
}
*/
void build() {
  for (int i = n - 1; i >= 0; i--) {
    sz[i]++;
    sz[r[i]] += sz[i];
  }
  rep(at, n) {
    if (at) {
      p[at].push_back(r[at]);
      for (int ch = 1, k = 0; ch * 2 <= h[at]; ch *= 2, k++) {
        p[at].push_back(p[p[at][k]][k]);
      }
    }
    int t = x[at] + 1;
    rep(i, g[at].size()) {
      int to = g[at][i];
      h[to] = h[at] + 1;
      x[to] = t;
      t += sz[to];
    }
    y[at] = t;
  }
}

int get(int at, int h) {
  if (h == 0)
    return at;
  int ch = 1, k = 0;
  while (ch * 2 <= h)
    ch *= 2, k++;
  return get(p[at][k], h - ch);
}

int common(int a, int b) {
  if (h[a] < h[b])
    swap(a, b);
  if (get(a, h[a] - h[b]) == b)
    return b;
  int l = 0, r = h[b];
  while (r - l > 1) {
    const int mid = (l + r) / 2;
    if (get(a, h[a] - mid) == get(b, h[b] - mid))
      l = mid;
    else
      r = mid;
  }
  return get(a, h[a] - l);
}

/*
int common(int u, int v) {
    if (h[u] > h[v]) swap(u, v);
    while (x[v] < x[u] || y[u] <= x[v]) {
//        printf("%d\\n", u);
        u = r[u];
    }
    return u;
}
*/

void add(int v, int a) {
  A.add(x[v], a);
  A.add(y[v], -a);
  B.add(x[v], -a * h[v]);
  B.add(y[v], a * h[v]);
}

Int f(int v) { return A.sum(x[v]) * h[v] + B.sum(x[v]); }

Int solve(int u, int v) {
  int g = common(u, v);
  Int t = f(g);
  //    printf("%d: %lld\\n", u, f(u));
  //    printf("%d: %lld\\n", v, f(v));
  //    printf("%d: %lld\\n", g, f(g));
  return f(u) - t + f(v) - t;
}

int main() {
  scanf("%d%d", &n, &Q);
  rep(i, n - 1) {
    int a, b;
    scanf("%d%d", &a, &b);
    g[a].push_back(b);
    r[b] = a;
  }
  //    rec(0, -1);
  build();
  //    rep (i, n) printf("%d, %d, %d, %d\\n", i, x[i], y[i], d[i]);
  rep(_, Q) {
    int t, u, v;
    scanf("%d%d%d", &t, &u, &v);
    //        printf("%d, %d, %d\\n", t, u, v);
    if (t == 0)
      printf("%lld\\n", solve(u, v));
    else
      add(u, v);
  }
  return 0;
}

Error: 0

Fixed submission:

#include <stdio.h>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long Int;
#define NUM (400000)

struct BIT {
  static const int N = NUM;
  Int x[N];
  void add(int k, Int a) {
    for (; k < N; k |= k + 1)
      x[k] += a;
  }
  Int sum(int k) {
    Int s = 0;
    for (; k >= 0; k = (k & (k + 1)) - 1)
      s += x[k];
    return s;
  }
} A, B;

int n, Q;
vector<int> g[NUM], p[NUM];
int _i, x[NUM], y[NUM], h[NUM], r[NUM];

void rec(int at, int pre) {
  if (pre != -1) {
    p[at].push_back(pre);
    for (int ch = 1, k = 0; ch * 2 <= h[at]; ch *= 2, k++) {
      p[at].push_back(p[p[at][k]][k]);
    }
  }
  x[at] = _i++;
  rep(i, g[at].size()) {
    h[g[at][i]] = h[at] + 1;
    rec(g[at][i], at);
  }
  y[at] = _i;
}

int get(int at, int h) {
  if (h == 0)
    return at;
  int ch = 1, k = 0;
  while (ch * 2 <= h)
    ch *= 2, k++;
  return get(p[at][k], h - ch);
}

int common(int a, int b) {
  if (h[a] < h[b])
    swap(a, b);
  if (get(a, h[a] - h[b]) == b)
    return b;
  int l = 0, r = h[b];
  while (r - l > 1) {
    const int mid = (l + r) / 2;
    if (get(a, h[a] - mid) == get(b, h[b] - mid))
      l = mid;
    else
      r = mid;
  }
  return get(a, h[a] - l);
}

/*
int common(int u, int v) {
    if (h[u] > h[v]) swap(u, v);
    while (x[v] < x[u] || y[u] <= x[v]) {
//        printf("%d\\n", u);
        u = r[u];
    }
    return u;
}
*/

void add(int v, int a) {
  A.add(x[v], a);
  A.add(y[v], -a);
  B.add(x[v], -a * h[v]);
  B.add(y[v], a * h[v]);
}

Int f(int v) { return A.sum(x[v]) * h[v] + B.sum(x[v]); }

Int solve(int u, int v) {
  int g = common(u, v);
  Int t = f(g);
  //    printf("%d: %lld\\n", u, f(u));
  //    printf("%d: %lld\\n", v, f(v));
  //    printf("%d: %lld\\n", g, f(g));
  return f(u) - t + f(v) - t;
}

int main() {
  scanf("%d%d", &n, &Q);
  rep(i, n - 1) {
    int a, b;
    scanf("%d%d", &a, &b);
    g[a].push_back(b);
    r[b] = a;
  }
  rec(0, -1);
  //    rep (i, n) printf("%d, %d, %d, %d\\n", i, x[i], y[i], d[i]);
  rep(_, Q) {
    int t, u, v;
    scanf("%d%d%d", &t, &u, &v);
    //        printf("%d, %d, %d\\n", t, u, v);
    if (t == 0)
      printf("%lld\\n", solve(u, v));
    else
      add(u, v);
  }
  return 0;
}