Problem p03656 (C++)

Buggy submission (status: Runtime Error):
/********************************************************************************

        Code by a weak man who named CYJian, and he hopes the code can get more
 points.

        Algorithm:

 ********************************************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge                                                                     \
  (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin),               \
               (iS == iT ? EOF : *iS++))                                       \
            : *iS++)
#define ri read_int()
#define rl read_ll()
#define FILE(s) freopen(s "in", "r", stdin), freopen(s "out", "w", stdout)

template <typename T> inline void read(T &x) {
  char ch, t = 0;
  x = 0;
  while (!isdigit(ch = ge))
    t |= ch == '-';
  while (isdigit(ch))
    x = x * 10 + (ch ^ 48), ch = ge;
  x = t ? -x : x;
}
inline int read_int() {
  int x;
  return read(x), x;
}
inline ll read_ll() {
  ll x;
  return read(x), x;
}

template <typename T> inline void chkmin(T &a, T b) { a = a < b ? a : b; }

const int MAXN = 100010;

int n;

struct UFS {
  int fa[MAXN];
  int d[MAXN];

  inline void init() {
    for (int i = 1; i <= n; i++)
      fa[i] = i;
  }
  inline int find(int x) {
    if (fa[x] == x)
      return x;
    int f = find(x);
    fa[x] = f, d[x] ^= d[f];
    return f;
  }
  inline void Merge(int u, int v) {
    int fu = find(u), fv = find(v);
    if (fu != fv)
      fa[fu] = fv, d[fu] = d[u] ^ d[v] ^ 1;
  }
  inline int val(int x) { return find(x), d[x]; }
} ufs;

struct WORK {
  vector<int> to[MAXN];
  int deg[MAXN];
  int id[MAXN];
  int rt;

  inline int dfs(int x) {
    vector<int> v;
    for (auto u : to[x])
      v.push_back(dfs(u));
    if (deg[x])
      v.push_back(x);
    sort(v.begin(), v.end());
    for (int i = 1; i < v.size(); i += 2)
      ufs.Merge(v[i], v[i + 1]);
    return v[0];
  }

  inline void solve() {
    for (int i = 1; i <= n; i++)
      deg[i] = 1, id[i] = i;
    for (int i = 1; i <= n; i++) {
      int f = ri;
      if (~f)
        to[f].push_back(i), deg[f] ^= 1;
      else
        rt = i;
    }
    dfs(rt);
  }
} A, B;

int main() {
#ifdef LOCAL
  FILE("");
#endif
  n = ri, ufs.init(), A.solve(), B.solve();
  for (int i = 1; i <= n; i++)
    if (A.deg[i] ^ B.deg[i])
      return puts("IMPOSSIBLE"), 0;
  puts("POSSIBLE");
  for (int i = 1; i <= n; i++)
    printf("%d%c", A.deg[i] * (ufs.val(i) ? 1 : -1), " \n"[i == n]);
  return 0;
}

Fixed submission:
/********************************************************************************

        Code by a weak man who named CYJian, and he hopes the code can get more
 points.

        Algorithm:

 ********************************************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge                                                                     \
  (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin),               \
               (iS == iT ? EOF : *iS++))                                       \
            : *iS++)
#define ri read_int()
#define rl read_ll()
#define FILE(s) freopen(s "in", "r", stdin), freopen(s "out", "w", stdout)

template <typename T> inline void read(T &x) {
  char ch, t = 0;
  x = 0;
  while (!isdigit(ch = ge))
    t |= ch == '-';
  while (isdigit(ch))
    x = x * 10 + (ch ^ 48), ch = ge;
  x = t ? -x : x;
}
inline int read_int() {
  int x;
  return read(x), x;
}
inline ll read_ll() {
  ll x;
  return read(x), x;
}

template <typename T> inline void chkmin(T &a, T b) { a = a < b ? a : b; }

const int MAXN = 100010;

int n;

struct UFS {
  int fa[MAXN];
  int d[MAXN];

  inline void init() {
    for (int i = 1; i <= n; i++)
      fa[i] = i;
  }
  inline int find(int x) {
    return fa[x] == x ? x : (find(fa[x]), d[x] ^= d[fa[x]], fa[x] = fa[fa[x]]);
  }
  inline void Merge(int u, int v) {
    int fu = find(u), fv = find(v);
    if (fu != fv)
      fa[fu] = fv, d[fu] = d[u] ^ d[v] ^ 1;
  }
  inline int val(int x) { return find(x), d[x]; }
} ufs;

struct WORK {
  vector<int> to[MAXN];
  int deg[MAXN];
  int id[MAXN];
  int rt;

  inline int dfs(int x) {
    vector<int> v;
    for (auto u : to[x])
      v.push_back(dfs(u));
    if (deg[x])
      v.push_back(x);
    sort(v.begin(), v.end());
    for (int i = 1; i < v.size(); i += 2)
      ufs.Merge(v[i], v[i + 1]);
    return v[0];
  }

  inline void solve() {
    for (int i = 1; i <= n; i++)
      deg[i] = 1, id[i] = i;
    for (int i = 1; i <= n; i++) {
      int f = ri;
      if (~f)
        to[f].push_back(i), deg[f] ^= 1;
      else
        rt = i;
    }
    dfs(rt);
  }
} A, B;

int main() {
#ifdef LOCAL
  FILE("");
#endif
  n = ri, ufs.init(), A.solve(), B.solve();
  for (int i = 1; i <= n; i++)
    if (A.deg[i] ^ B.deg[i])
      return puts("IMPOSSIBLE"), 0;
  puts("POSSIBLE");
  for (int i = 1; i <= n; i++)
    printf("%d%c", A.deg[i] * (ufs.val(i) ? 1 : -1), " \n"[i == n]);
  return 0;
}