Problem p03727 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAXN = 200010;
const int INF = 1e9;
int _w;

int T, n;
pii pr[MAXN];

namespace Tree {
int head[MAXN], nxt[MAXN << 1], to[MAXN << 1], m;
void init() {
  m = 0;
  for (int i = 1; i <= n; ++i)
    head[i] = -1;
}
void adde(int u, int v) {
  to[m] = v, nxt[m] = head[u], head[u] = m++;
  to[m] = u, nxt[m] = head[v], head[v] = m++;
}
} // namespace Tree

namespace SGT {
ll sum[MAXN << 2], addc[MAXN << 2], adds[MAXN << 2], minc[MAXN << 2];
void maintain(int o, int L, int R) {
  if (L == R)
    return;
  int lc = o << 1, rc = lc | 1;
  minc[o] = min(minc[lc], minc[rc]) + addc[o];
}
void pushdown(int o, int L, int R) {
  if (L == R) {
    sum[o] += adds[o];
    adds[o] = 0;
  } else {
    int lc = o << 1, rc = lc | 1;
    adds[lc] += adds[o];
    adds[rc] += adds[o];
    adds[o] = 0;
    addc[lc] += addc[o], minc[lc] += addc[o];
    addc[rc] += addc[o], minc[rc] += addc[o];
    addc[o] = 0;
  }
}
void _init(int o, int L, int R) {
  sum[o] = addc[o] = adds[o] = minc[o] = 0;
  if (L == 1 && R == 1)
    minc[o] = INF;
  if (L == R)
    return;
  int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
  _init(lc, L, M), _init(rc, M + 1, R);
  maintain(o, L, R);
}
void init() { _init(1, 1, n); }
int ql, qr, qv;
void _add(int o, int L, int R) {
  pushdown(o, L, R);
  if (L >= ql && R <= qr) {
    adds[o] += qv;
    ++addc[o], ++minc[o];
  } else {
    int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
    if (ql <= M)
      _add(lc, L, M);
    if (qr > M)
      _add(rc, M + 1, R);
    maintain(o, L, R);
  }
}
void add(int l, int r, int v) {
  ql = l, qr = r, qv = v;
  _add(1, 1, n);
}
int query() {
  if (minc[1] != 1)
    return -1;
  int o = 1, L = 1, R = n;
  while (L < R) {
    pushdown(o, L, R);
    int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
    if (minc[lc] == 1)
      o = lc, R = M;
    else
      o = rc, L = M + 1;
  }
  pushdown(o, L, R);
  return (int)sum[o];
}
void _del(int o, int L, int R) {
  pushdown(o, L, R);
  if (L >= ql && R <= qr) {
    adds[o] -= qv;
    --addc[o], --minc[o];
  } else {
    int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
    if (ql <= M)
      _del(lc, L, M);
    if (qr > M)
      _del(rc, M + 1, R);
    maintain(o, L, R);
  }
}
void _adjust(int o, int L, int R) {
  pushdown(o, L, R);
  if (L == R) {
    minc[o] = INF;
  } else {
    int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
    if (!minc[lc])
      _adjust(lc, L, M);
    if (!minc[rc])
      _adjust(rc, M + 1, R);
    maintain(o, L, R);
  }
}
void del(int l, int r, int v) {
  ql = l, qr = r, qv = v;
  _del(1, 1, n);
  _adjust(1, 1, n);
}
} // namespace SGT

namespace DFN {
int dfn[MAXN], dfnc, dep[MAXN], sz[MAXN], son[MAXN], pa[MAXN], top[MAXN];
void dfs1(int u, int fa, int d) {
  using namespace Tree;
  dep[u] = d, pa[u] = fa, sz[u] = 1, son[u] = 0;
  for (int i = head[u]; ~i; i = nxt[i]) {
    int v = to[i];
    if (v == fa)
      continue;
    dfs1(v, u, d + 1);
    sz[u] += sz[v];
    if (sz[v] > sz[son[u]])
      son[u] = v;
  }
}
void dfs2(int u, int tp) {
  using namespace Tree;
  dfn[u] = ++dfnc, top[u] = tp;
  if (son[u])
    dfs2(son[u], tp);
  for (int i = head[u]; ~i; i = nxt[i]) {
    int v = to[i];
    if (v == pa[u] || v == son[u])
      continue;
    dfs2(v, v);
  }
}
void solve() {
  dfs1(1, 0, 1);
  dfnc = 0;
  dfs2(1, 1);
  SGT::init();
}
void addpath(int u, int v, int w) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]])
      swap(u, v);
    SGT::add(dfn[top[u]], dfn[u], w);
    u = pa[top[u]];
  }
  if (dep[u] > dep[v])
    swap(u, v);
  if (u != v)
    SGT::add(dfn[u] + 1, dfn[v], w);
}
int query() { return SGT::query(); }
void delpath(int u, int v, int w) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]])
      swap(u, v);
    SGT::del(dfn[top[u]], dfn[u], w);
    u = pa[top[u]];
  }
  if (dep[u] > dep[v])
    swap(u, v);
  if (u != v)
    SGT::del(dfn[u] + 1, dfn[v], w);
}
} // namespace DFN

int main() {
  _w = scanf("%d", &T);
  while (T--) {
    _w = scanf("%d", &n);
    Tree::init();
    for (int i = 0; i < n - 1; ++i) {
      int u, v;
      _w = scanf("%d%d", &u, &v);
      Tree::adde(u, v);
    }
    DFN::solve();
    for (int i = 1; i <= n - 1; ++i) {
      int u, v;
      _w = scanf("%d%d", &u, &v);
      pr[i] = pii(u, v);
      DFN::addpath(u, v, i);
    }
    bool flag = true;
    for (int i = 0; i < n - 1; ++i) {
      int id = DFN::query();
      if (id == -1) {
        flag = false;
        break;
      }
      DFN::delpath(pr[id].first, pr[id].second, id);
    }
    puts(flag ? "YES" : "NO");
  }
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAXN = 200010;
const int INF = 1e9;
int _w;

int T, n;
pii pr[MAXN];

namespace Tree {
int head[MAXN], nxt[MAXN << 1], to[MAXN << 1], m;
void init() {
  m = 0;
  for (int i = 1; i <= n; ++i)
    head[i] = -1;
}
void adde(int u, int v) {
  to[m] = v, nxt[m] = head[u], head[u] = m++;
  to[m] = u, nxt[m] = head[v], head[v] = m++;
}
} // namespace Tree

namespace SGT {
ll sum[MAXN << 2], addc[MAXN << 2], adds[MAXN << 2], minc[MAXN << 2];
void maintain(int o, int L, int R) {
  if (L == R)
    return;
  int lc = o << 1, rc = lc | 1;
  minc[o] = min(minc[lc], minc[rc]) + addc[o];
}
void pushdown(int o, int L, int R) {
  if (L == R) {
    sum[o] += adds[o];
    adds[o] = 0;
  } else {
    int lc = o << 1, rc = lc | 1;
    adds[lc] += adds[o];
    adds[rc] += adds[o];
    adds[o] = 0;
    addc[lc] += addc[o], minc[lc] += addc[o];
    addc[rc] += addc[o], minc[rc] += addc[o];
    addc[o] = 0;
  }
}
void _init(int o, int L, int R) {
  sum[o] = addc[o] = adds[o] = minc[o] = 0;
  if (L == 1 && R == 1)
    minc[o] = INF;
  if (L == R)
    return;
  int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
  _init(lc, L, M), _init(rc, M + 1, R);
  maintain(o, L, R);
}
void init() { _init(1, 1, n); }
int ql, qr, qv;
void _add(int o, int L, int R) {
  pushdown(o, L, R);
  if (L >= ql && R <= qr) {
    adds[o] += qv;
    ++addc[o], ++minc[o];
  } else {
    int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
    if (ql <= M)
      _add(lc, L, M);
    if (qr > M)
      _add(rc, M + 1, R);
    maintain(o, L, R);
  }
}
void add(int l, int r, int v) {
  ql = l, qr = r, qv = v;
  _add(1, 1, n);
}
int query() {
  if (minc[1] != 1)
    return -1;
  int o = 1, L = 1, R = n;
  while (L < R) {
    pushdown(o, L, R);
    int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
    if (minc[lc] == 1)
      o = lc, R = M;
    else
      o = rc, L = M + 1;
  }
  pushdown(o, L, R);
  return (int)sum[o];
}
void _del(int o, int L, int R) {
  pushdown(o, L, R);
  if (L >= ql && R <= qr) {
    adds[o] -= qv;
    --addc[o], --minc[o];
  } else {
    int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
    if (ql <= M)
      _del(lc, L, M);
    if (qr > M)
      _del(rc, M + 1, R);
    maintain(o, L, R);
  }
}
void _adjust(int o, int L, int R) {
  pushdown(o, L, R);
  if (L == R) {
    minc[o] = INF;
  } else {
    int lc = o << 1, rc = lc | 1, M = (L + R) >> 1;
    if (!minc[lc])
      _adjust(lc, L, M);
    if (!minc[rc])
      _adjust(rc, M + 1, R);
    maintain(o, L, R);
  }
}
void del(int l, int r, int v) {
  ql = l, qr = r, qv = v;
  _del(1, 1, n);
  _adjust(1, 1, n);
}
} // namespace SGT

namespace DFN {
int dfn[MAXN], dfnc, dep[MAXN], sz[MAXN], son[MAXN], pa[MAXN], top[MAXN];
void dfs1(int u, int fa, int d) {
  using namespace Tree;
  dep[u] = d, pa[u] = fa, sz[u] = 1, son[u] = 0;
  for (int i = head[u]; ~i; i = nxt[i]) {
    int v = to[i];
    if (v == fa)
      continue;
    dfs1(v, u, d + 1);
    sz[u] += sz[v];
    if (sz[v] > sz[son[u]])
      son[u] = v;
  }
}
void dfs2(int u, int tp) {
  using namespace Tree;
  dfn[u] = ++dfnc, top[u] = tp;
  if (son[u])
    dfs2(son[u], tp);
  for (int i = head[u]; ~i; i = nxt[i]) {
    int v = to[i];
    if (v == pa[u] || v == son[u])
      continue;
    dfs2(v, v);
  }
}
void solve() {
  dfs1(1, 0, 1);
  dfnc = 0;
  dfs2(1, 1);
  SGT::init();
}
void addpath(int u, int v, int w) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]])
      swap(u, v);
    SGT::add(dfn[top[u]], dfn[u], w);
    u = pa[top[u]];
  }
  if (dep[u] > dep[v])
    swap(u, v);
  if (u != v)
    SGT::add(dfn[u] + 1, dfn[v], w);
}
int query() { return SGT::query(); }
void delpath(int u, int v, int w) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]])
      swap(u, v);
    SGT::del(dfn[top[u]], dfn[u], w);
    u = pa[top[u]];
  }
  if (dep[u] > dep[v])
    swap(u, v);
  if (u != v)
    SGT::del(dfn[u] + 1, dfn[v], w);
}
} // namespace DFN

int main() {
  // _w = scanf( "%d", &T );
  T = 1;
  while (T--) {
    _w = scanf("%d", &n);
    Tree::init();
    for (int i = 0; i < n - 1; ++i) {
      int u, v;
      _w = scanf("%d%d", &u, &v);
      Tree::adde(u, v);
    }
    DFN::solve();
    for (int i = 1; i <= n - 1; ++i) {
      int u, v;
      _w = scanf("%d%d", &u, &v);
      pr[i] = pii(u, v);
      DFN::addpath(u, v, i);
    }
    bool flag = true;
    for (int i = 0; i < n - 1; ++i) {
      int id = DFN::query();
      if (id == -1) {
        flag = false;
        break;
      }
      DFN::delpath(pr[id].first, pr[id].second, id);
    }
    puts(flag ? "YES" : "NO");
  }
  return 0;
}