Problem p03368 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define title "title"
#define ll long long
#define ull unsigned ll
#define fix(x) fixed << setprecision(x)
using namespace std;
void Freopen() {
  freopen(title ".in", "r", stdin);
  freopen(title ".out", "w", stdout);
}
ll read() {
  ll g = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || '9' < ch) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while ('0' <= ch && ch <= '9') {
    g = g * 10 + ch - '0';
    ch = getchar();
  }
  return g * f;
}
const ll N = 30005;
ll h[N], cnt, pr[N], f[N], siz[N], sum[N], Ans, ans, n, w[N], a[N], prt[N];
struct Edge {
  ll to, ne;
} e[N << 1];
struct node {
  ll x, sum, siz;
  bool operator<(const node &other) const {
    return sum * other.siz < other.sum * siz;
  }
};
void add(ll x, ll y) {
  e[++cnt] = Edge{y, h[x]};
  h[x] = cnt;
}
void dfs(ll x, ll anc) {
  if (a[x])
    prt[x] = anc, anc = x;
  else
    w[anc]++;
  for (ll i = h[x]; i; i = e[i].ne)
    dfs(e[i].to, anc);
}
ll get(ll x) { return (f[x] == x ? x : f[x] = get(f[x])); }
void solve(ll x) {
  Ans = 0;
  priority_queue<node> q;
  siz[0] = 1;
  for (ll i = 1; i <= n; i++)
    if (~prt[i])
      f[i] = i, siz[i] = 1, sum[i] = w[i], q.push(node{i, w[i], 1});
  while (true) {
    while (!q.empty() && q.top().siz != siz[q.top().x])
      q.pop();
    if (q.empty())
      break;
    ll x = q.top().x;
    q.pop();
    if (prt[x] == -1)
      continue;
    Ans += siz[get(prt[x])] * sum[x];
    f[x] = get(prt[x]);
    siz[get(prt[x])] += siz[x];
    sum[get(prt[x])] += sum[x];
    q.push(node{get(prt[x]), sum[get(prt[x])], siz[get(prt[x])]});
  }
  ans = Ans;
}
signed main() {
  n = read();
  add(0, 1);
  for (int i = 2; i <= n; i++)
    pr[i] = read(), add(pr[i], i);
  a[0] = 1;
  for (ll i = 1; i <= n; i++)
    a[i] = read();
  memset(prt, -1, sizeof(prt));
  dfs(0, 0);
  prt[0] = -1;
  return solve(0), cout << ans, signed();
}

Fixed submission:
#include <bits/stdc++.h>
#define title "title"
#define ll long long
#define ull unsigned ll
#define fix(x) fixed << setprecision(x)
using namespace std;
void Freopen() {
  freopen(title ".in", "r", stdin);
  freopen(title ".out", "w", stdout);
}
ll read() {
  ll g = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || '9' < ch) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while ('0' <= ch && ch <= '9') {
    g = g * 10 + ch - '0';
    ch = getchar();
  }
  return g * f;
}
const ll N = 2e5 + 5;
ll h[N], cnt, pr[N], f[N], siz[N], sum[N], Ans, ans, n, w[N], a[N], prt[N];
struct Edge {
  ll to, ne;
} e[N << 1];
struct node {
  ll x, sum, siz;
  bool operator<(const node &other) const {
    return sum * other.siz < other.sum * siz;
  }
};
void add(ll x, ll y) {
  e[++cnt] = Edge{y, h[x]};
  h[x] = cnt;
}
void dfs(ll x, ll anc) {
  if (a[x])
    prt[x] = anc, anc = x;
  else
    w[anc]++;
  for (ll i = h[x]; i; i = e[i].ne)
    dfs(e[i].to, anc);
}
ll get(ll x) { return (f[x] == x ? x : f[x] = get(f[x])); }
void solve(ll x) {
  Ans = 0;
  priority_queue<node> q;
  siz[0] = 1;
  for (ll i = 1; i <= n; i++)
    if (~prt[i])
      f[i] = i, siz[i] = 1, sum[i] = w[i], q.push(node{i, w[i], 1});
  while (true) {
    while (!q.empty() && q.top().siz != siz[q.top().x])
      q.pop();
    if (q.empty())
      break;
    ll x = q.top().x;
    q.pop();
    if (prt[x] == -1)
      continue;
    Ans += siz[get(prt[x])] * sum[x];
    f[x] = get(prt[x]);
    siz[get(prt[x])] += siz[x];
    sum[get(prt[x])] += sum[x];
    q.push(node{get(prt[x]), sum[get(prt[x])], siz[get(prt[x])]});
  }
  ans = Ans;
}
signed main() {
  n = read();
  add(0, 1);
  for (int i = 2; i <= n; i++)
    pr[i] = read(), add(pr[i], i);
  a[0] = 1;
  for (ll i = 1; i <= n; i++)
    a[i] = read();
  memset(prt, -1, sizeof(prt));
  dfs(0, 0);
  prt[0] = -1;
  return solve(0), cout << ans, signed();
}