Problem p02986 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
using namespace std;
int n, T, num, tot;
int rdt[200300], rd[200300], rdc[200300], rdl[200300], wz[200300], ans[200300];
int dad[200300], hvdad[200300], hvson[200300], dep[200300], sz[200300],
    dadlen[200300];
int trtoli[200300], litotr[200300];
int a[400300], sum[400300], L[400300], R[400300];

struct SS {
  int ans, sum;
};

struct S {
  int l, c, x, y, n;
} A[200050], Q[200050];

void cnct(int x, int y, int c, int l) {
  rdt[++num] = wz[x], rd[num] = y, rdc[num] = c, rdl[num] = l, wz[x] = num;
  rdt[++num] = wz[y], rd[num] = x, rdc[num] = c, rdl[num] = l, wz[y] = num;
}

void dfs(int x, int from, int l, int d) {
  int t = wz[x], m = 0;
  dad[x] = from, sz[x] = 1, dadlen[x] = l, dep[x] = d;
  while (t) {
    if (rd[t] != from) {
      dfs(rd[t], x, rdl[t], d + 1);
      if (sz[rd[t]] > m)
        m = sz[rd[t]], hvson[x] = rd[t];
      sz[x]++;
    }
    t = rdt[t];
  }
}

void dfs2(int x, int hd) {
  int t = wz[x];
  trtoli[x] = ++num, hvdad[x] = hd;
  litotr[num] = x;
  if (hvson[x])
    dfs2(hvson[x], hd);
  while (t) {
    if (rd[t] != dad[x] && rd[t] != hvson[x]) {
      dfs2(rd[t], rd[t]);
    }
    t = rdt[t];
  }
}

void Mk(int x, int l, int r) {
  L[x] = l, R[x] = r;
  if (l != r) {
    Mk(x * 2, l, (l + r) / 2);
    Mk(x * 2 + 1, (l + r) / 2 + 1, r);
    a[x] = a[x * 2] + a[x * 2 + 1];
  } else {
    a[x] = dadlen[litotr[l]];
  }
}

bool cmp(S t1, S t2) { return t1.c < t2.c; }

void updt(int x, int tar, int num, int ty) {
  if (L[x] == R[x]) {
    a[x] = num, sum[x] = ty;
  } else {
    if (tar < L[x * 2 + 1])
      updt(x * 2, tar, num, ty);
    else
      updt(x * 2 + 1, tar, num, ty);
    a[x] = a[x * 2] + a[x * 2 + 1];
    sum[x] = sum[x * 2] + sum[x * 2 + 1];
  }
}

void chg(int x, int y) {
  int tar, tarnum = y;
  if (dad[A[x].x] == A[x].y)
    tar = trtoli[A[x].x];
  else
    tar = trtoli[A[x].y];
  updt(1, tar, tarnum, 1);
}

void rechg(int x) {
  int tar, tarnum = A[x].l;
  if (dad[A[x].x] == A[x].y)
    tar = trtoli[A[x].x];
  else
    tar = trtoli[A[x].y];
  updt(1, tar, tarnum, 0);
}

SS getsum(int x, int l, int r) {
  if (L[x] == R[x]) {
    SS P;
    P.ans = a[x];
    P.sum = sum[x];
    return P;
  } else {
    if (r < L[x * 2 + 1])
      return getsum(x * 2, l, r);
    else if (l > R[x * 2])
      return getsum(x * 2 + 1, l, r);
    else {
      SS P = getsum(x * 2, l, R[x * 2]),
         PP = getsum(x * 2 + 1, L[x * 2 + 1], r);
      P.ans += PP.ans, P.sum += PP.sum;
      return P;
    }
  }
}

int getans(int x, int y, int t1, int t2) {
  int ans = 0, sum = 0;
  SS P;
  while (hvdad[x] != hvdad[y]) {
    if (dep[hvdad[x]] < dep[hvdad[y]])
      swap(x, y);
    P = getsum(1, trtoli[hvdad[x]], trtoli[x]);
    ans += P.ans, sum += P.sum;
    x = dad[hvdad[x]];
  }
  if (x != y) {
    if (dep[x] < dep[y])
      swap(x, y);
    P = getsum(1, trtoli[y] + 1, trtoli[x]);
    ans += P.ans, sum += P.sum;
  }
  return ans + sum * (Q[t2].l - Q[t1].l);
}

int main() {
  int i, j, k, i2, j2;
  scanf("%d%d", &n, &T);
  for (i = 1; i < n; i++) {
    scanf("%d%d%d%d", &A[i].x, &A[i].y, &A[i].c, &A[i].l);
    cnct(A[i].x, A[i].y, A[i].c, A[i].l), A[i].n = i;
  }
  for (i = 1; i <= T; i++)
    scanf("%d%d%d%d", &Q[i].c, &Q[i].l, &Q[i].x, &Q[i].y), Q[i].n = i;
  num = 0;
  dfs(1, 0, 0, 0);
  dfs2(1, 1);
  Mk(1, 1, num);
  sort(A + 1, A + n, cmp);
  sort(Q + 1, Q + 1 + T, cmp);
  i2 = 0;
  for (i = 1; i <= T; i++) {
    int pd = 0;
    while (A[++i2].c < Q[i].c && i2 < n)
      ;
    if (A[i2].c == Q[i].c) {
      for (j2 = i2; A[j2].c == Q[i].c; j2++) {
        chg(j2, Q[i].l);
      }
      pd = 1;
    } else
      i2--;
    for (j = i + 1; j <= T; j++)
      if (Q[j].c != Q[i].c)
        break;
    for (k = i; k < j; k++) {
      ans[Q[k].n] = getans(Q[k].x, Q[k].y, i, k);
    }
    if (pd) {
      for (j2 = i2; A[j2].c == Q[i].c; j2++) {
        rechg(j2);
      }
      i2 = j2 - 1;
    }
    i = j - 1;
  }
  for (i = 1; i <= T; i++)
    printf("%d\n", ans[i]);
}

Fixed submission:
#include <algorithm>
#include <cstdio>
using namespace std;
int n, T, num, tot;
int rdt[200300], rd[200300], rdc[200300], rdl[200300], wz[200300], ans[200300];
int dad[200300], hvdad[200300], hvson[200300], dep[200300], sz[200300],
    dadlen[200300];
int trtoli[200300], litotr[200300];
int a[400300], sum[400300], L[400300], R[400300];

struct SS {
  int ans, sum;
};

struct S {
  int l, c, x, y, n;
} A[200050], Q[200050];

void cnct(int x, int y, int c, int l) {
  rdt[++num] = wz[x], rd[num] = y, rdc[num] = c, rdl[num] = l, wz[x] = num;
  rdt[++num] = wz[y], rd[num] = x, rdc[num] = c, rdl[num] = l, wz[y] = num;
}

void dfs(int x, int from, int l, int d) {
  int t = wz[x], m = 0;
  dad[x] = from, sz[x] = 1, dadlen[x] = l, dep[x] = d;
  while (t) {
    if (rd[t] != from) {
      dfs(rd[t], x, rdl[t], d + 1);
      if (sz[rd[t]] > m)
        m = sz[rd[t]], hvson[x] = rd[t];
      sz[x]++;
    }
    t = rdt[t];
  }
}

void dfs2(int x, int hd) {
  int t = wz[x];
  trtoli[x] = ++num, hvdad[x] = hd;
  litotr[num] = x;
  if (hvson[x])
    dfs2(hvson[x], hd);
  while (t) {
    if (rd[t] != dad[x] && rd[t] != hvson[x]) {
      dfs2(rd[t], rd[t]);
    }
    t = rdt[t];
  }
}

void Mk(int x, int l, int r) {
  L[x] = l, R[x] = r;
  if (l != r) {
    Mk(x * 2, l, (l + r) / 2);
    Mk(x * 2 + 1, (l + r) / 2 + 1, r);
    a[x] = a[x * 2] + a[x * 2 + 1];
  } else {
    a[x] = dadlen[litotr[l]];
  }
}

bool cmp(S t1, S t2) { return t1.c < t2.c; }

void updt(int x, int tar, int num, int ty) {
  if (L[x] == R[x]) {
    a[x] = num, sum[x] = ty;
  } else {
    if (tar < L[x * 2 + 1])
      updt(x * 2, tar, num, ty);
    else
      updt(x * 2 + 1, tar, num, ty);
    a[x] = a[x * 2] + a[x * 2 + 1];
    sum[x] = sum[x * 2] + sum[x * 2 + 1];
  }
}

void chg(int x, int y) {
  int tar, tarnum = y;
  if (dad[A[x].x] == A[x].y)
    tar = trtoli[A[x].x];
  else
    tar = trtoli[A[x].y];
  updt(1, tar, tarnum, 1);
}

void rechg(int x) {
  int tar, tarnum = A[x].l;
  if (dad[A[x].x] == A[x].y)
    tar = trtoli[A[x].x];
  else
    tar = trtoli[A[x].y];
  updt(1, tar, tarnum, 0);
}

SS getsum(int x, int l, int r) {
  if (L[x] == l && R[x] == r) {
    SS P;
    P.ans = a[x];
    P.sum = sum[x];
    return P;
  } else {
    if (r < L[x * 2 + 1])
      return getsum(x * 2, l, r);
    else if (l > R[x * 2])
      return getsum(x * 2 + 1, l, r);
    else {
      SS P = getsum(x * 2, l, R[x * 2]),
         PP = getsum(x * 2 + 1, L[x * 2 + 1], r);
      P.ans += PP.ans, P.sum += PP.sum;
      return P;
    }
  }
}

int getans(int x, int y, int t1, int t2) {
  int ans = 0, sum = 0;
  SS P;
  while (hvdad[x] != hvdad[y]) {
    if (dep[hvdad[x]] < dep[hvdad[y]])
      swap(x, y);
    P = getsum(1, trtoli[hvdad[x]], trtoli[x]);
    ans += P.ans, sum += P.sum;
    x = dad[hvdad[x]];
  }
  if (x != y) {
    if (dep[x] < dep[y])
      swap(x, y);
    P = getsum(1, trtoli[y] + 1, trtoli[x]);
    ans += P.ans, sum += P.sum;
  }
  return ans + sum * (Q[t2].l - Q[t1].l);
}

int main() {
  int i, j, k, i2, j2;
  scanf("%d%d", &n, &T);
  for (i = 1; i < n; i++) {
    scanf("%d%d%d%d", &A[i].x, &A[i].y, &A[i].c, &A[i].l);
    cnct(A[i].x, A[i].y, A[i].c, A[i].l), A[i].n = i;
  }
  for (i = 1; i <= T; i++)
    scanf("%d%d%d%d", &Q[i].c, &Q[i].l, &Q[i].x, &Q[i].y), Q[i].n = i;
  num = 0;
  dfs(1, 0, 0, 0);
  dfs2(1, 1);
  Mk(1, 1, num);
  sort(A + 1, A + n, cmp);
  sort(Q + 1, Q + 1 + T, cmp);
  i2 = 0;
  for (i = 1; i <= T; i++) {
    int pd = 0;
    while (A[++i2].c < Q[i].c && i2 < n)
      ;
    if (A[i2].c == Q[i].c) {
      for (j2 = i2; A[j2].c == Q[i].c; j2++) {
        chg(j2, Q[i].l);
      }
      pd = 1;
    } else
      i2--;
    for (j = i + 1; j <= T; j++)
      if (Q[j].c != Q[i].c)
        break;
    for (k = i; k < j; k++) {
      ans[Q[k].n] = getans(Q[k].x, Q[k].y, i, k);
    }
    if (pd) {
      for (j2 = i2; A[j2].c == Q[i].c; j2++) {
        rechg(j2);
      }
      i2 = j2 - 1;
    }
    i = j - 1;
  }
  for (i = 1; i <= T; i++)
    printf("%d\n", ans[i]);
}