Problem p03368 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
template <typename T> inline void chkmin(T &a, const T &b) {
  a = a < b ? a : b;
}
template <typename T> inline void chkmax(T &a, const T &b) {
  a = a > b ? a : b;
}

const int MAXN = 200005;
int par[MAXN], fat[MAXN], val[MAXN], f[MAXN], g[MAXN], n;
struct Node {
  int f, g, id;
  bool operator<(const Node &a) const {
    LL x = (LL)f * a.g, y = (LL)g * a.f;
    return x == y ? id < a.id : x < y;
  }
  bool operator==(const Node &a) const {
    return id == a.id && f == a.f && g == a.g;
  }
};
struct Set {
  priority_queue<Node> ins, del;
  void upd() {
    while (!del.empty() && ins.top() == del.top())
      ins.pop(), del.pop();
  }
  void push(const Node &d) { ins.emplace(d); }
  void pop() {
    upd();
    ins.pop();
  }
  Node top() {
    upd();
    return ins.top();
  }
  bool empty() {
    upd();
    return ins.empty();
  }
  void erase(const Node &d) { del.emplace(d); }
} pq;
int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    par[i] = i;
  for (int i = 2; i <= n; i++)
    scanf("%d", fat + i);
  for (int i = 1; i <= n; i++) {
    scanf("%d", val + i);
    (val[i] ? g[i] : f[i]) = 1;
    if (i > 1) {
      if (val[i])
        pq.push(Node{0, 1, i});
      else
        pq.push(Node{1, 0, i});
    }
  }
  LL ans = 0;
  int cnt = 0;
  while (!pq.empty()) {
    assert(++cnt <= n - 1);
    Node d = pq.top();
    pq.pop();
    int v = find(d.id), u = find(fat[v]);
    assert(v == d.id);
    ans += (LL)g[u] * f[v];
    if (u > 1)
      pq.erase(Node{f[u], g[u], u});
    f[u] += f[v], g[u] += g[v];
    if (u > 1)
      pq.push(Node{f[u], g[u], u});
    par[v] = u;
  }
  printf("%lld\n", ans);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
template <typename T> inline void chkmin(T &a, const T &b) {
  a = a < b ? a : b;
}
template <typename T> inline void chkmax(T &a, const T &b) {
  a = a > b ? a : b;
}

const int MAXN = 200005;
int par[MAXN], fat[MAXN], val[MAXN], f[MAXN], g[MAXN], n;
struct Node {
  int f, g, id;
  bool operator<(const Node &a) const {
    LL x = (LL)f * a.g, y = (LL)g * a.f;
    return x == y ? id < a.id : x < y;
  }
  bool operator==(const Node &a) const {
    return id == a.id && (LL)f * a.g == (LL)g * a.f;
  }
};
struct Set {
  priority_queue<Node> ins, del;
  void upd() {
    while (!del.empty() && ins.top() == del.top())
      ins.pop(), del.pop();
  }
  void push(const Node &d) { ins.emplace(d); }
  void pop() {
    upd();
    ins.pop();
  }
  Node top() {
    upd();
    return ins.top();
  }
  bool empty() {
    upd();
    return ins.empty();
  }
  void erase(const Node &d) { del.emplace(d); }
} pq;
int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    par[i] = i;
  for (int i = 2; i <= n; i++)
    scanf("%d", fat + i);
  for (int i = 1; i <= n; i++) {
    scanf("%d", val + i);
    (val[i] ? g[i] : f[i]) = 1;
    if (i > 1) {
      if (val[i])
        pq.push(Node{0, 1, i});
      else
        pq.push(Node{1, 0, i});
    }
  }
  LL ans = 0;
  int cnt = 0;
  while (!pq.empty()) {
    assert(++cnt <= n - 1);
    Node d = pq.top();
    pq.pop();
    int v = find(d.id), u = find(fat[v]);
    assert(v == d.id);
    ans += (LL)g[u] * f[v];
    if (u > 1)
      pq.erase(Node{f[u], g[u], u});
    f[u] += f[v], g[u] += g[v];
    if (u > 1)
      pq.push(Node{f[u], g[u], u});
    par[v] = u;
  }
  printf("%lld\n", ans);
  return 0;
}