Problem p03499 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MAX = 2005;
const int MOD = 1000000007;
vector<int> g[MAX];

int pow2[MAX];

int add(int a, int b) { return (a + b) % MOD; }
int sub(int a, int b) { return ((ll)a - (ll)b + 2 * (ll)MOD) % MOD; }
int mult(int a, int b) { return ((ll)a * (ll)b) % MOD; }
int sq(int a) { return mult(a, a); }
int exp(int a, int b) {
  if (b == 0) {
    return 1;
  }
  if (b % 2 == 1) {
    return mult(a, sq(exp(a, b / 2)));
  } else {
    return sq(exp(a, b / 2));
  }
}
int inv(int a) { return exp(a, MOD - 2); }
int divi(int a, int b) { return mult(a, inv(b)); }

int d[MAX], dep[MAX];

struct trip {
  int v[3];
  trip(int a, int b, int c) {
    v[0] = a;
    v[1] = b;
    v[2] = c;
  }
};

trip comb(trip a, trip b) {
  trip c = trip(0, 0, 0);
  for (int i = 0; i <= 2; i++) {
    for (int j = 0; j <= 2; j++) {
      int n = min(2, i + j);
      c.v[n] = add(c.v[n], mult(a.v[i], b.v[j]));
    }
  }
  return c;
}

trip comp(trip a) { return trip(add(a.v[0], a.v[2]), a.v[1], 0); }

void print(trip a) { cout << a.v[0] << " " << a.v[1] << " " << a.v[2] << endl; }

vector<trip> dp[MAX];
int ct[MAX];
void dfs(int u) {
  dep[u] = 1;
  int maxd = -1;
  int id = 0;
  for (int i : g[u]) {
    d[i] = d[u] + 1;
    dfs(i);
    dep[u] = max(dep[u], dep[i] + 1);
    if (dep[i] > maxd) {
      maxd = dep[i];
      id = i;
    }
  }

  int maxsz = 0;
  for (int i : g[u]) {
    if (i == id) {
      continue;
    }
    maxsz = max(maxsz, (int)dp[i].size());
    // merge i with id
    for (int j = 0; j < dp[i].size(); j++) {
      int offset = (int)dp[id].size() - (int)dp[i].size();
      // dp[i][k]
      // the depth number is dp[i].size() - 1 - k
      // so dp[u].size() - dp[i].size() + k

      dp[id][j + offset] = comb(dp[id][j + offset], dp[i][j]);
    }
  }
  swap(dp[u], dp[id]);

  for (int i = 1; i <= maxsz; i++) {
    dp[u][dp[u].size() - i] = comp(dp[u][dp[u].size() - i]);
  }
  dp[u].push_back(trip(inv(2), inv(2), 0));
}

int main() {
  // freopen("a.in", "r", stdin);

  pow2[0] = 1;
  for (int i = 1; i < MAX; i++) {
    pow2[i] = (pow2[i - 1] * 2) % MOD;
  }
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int p;
    scanf("%d", &p);
    g[p].push_back(i);
  }
  d[0] = 1;
  dfs(0);
  for (int i = 0; i <= n; i++) {
    ct[d[i]]++;
  }
  reverse(dp[0].begin(), dp[0].end());
  int ans = 0;
  for (int i = 0; i < dp[0].size(); i++) {
    ans = add(ans, mult(pow2[n + 1], dp[0][i].v[1]));
  }
  printf("%d\n", ans);
  /*
  d[0] = 1;
  dfs(0);
  for (int i=1; i<=n+1; i++) {
          process(n, i);
  }
  printf("%d\n", ans);
  */
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MAX = 200005;
const int MOD = 1000000007;
vector<int> g[MAX];

int pow2[MAX];

int add(int a, int b) { return (a + b) % MOD; }
int sub(int a, int b) { return ((ll)a - (ll)b + 2 * (ll)MOD) % MOD; }
int mult(int a, int b) { return ((ll)a * (ll)b) % MOD; }
int sq(int a) { return mult(a, a); }
int exp(int a, int b) {
  if (b == 0) {
    return 1;
  }
  if (b % 2 == 1) {
    return mult(a, sq(exp(a, b / 2)));
  } else {
    return sq(exp(a, b / 2));
  }
}
int inv(int a) { return exp(a, MOD - 2); }
int divi(int a, int b) { return mult(a, inv(b)); }

int d[MAX], dep[MAX];

struct trip {
  int v[3];
  trip(int a, int b, int c) {
    v[0] = a;
    v[1] = b;
    v[2] = c;
  }
};

trip comb(trip a, trip b) {
  trip c = trip(0, 0, 0);
  for (int i = 0; i <= 2; i++) {
    for (int j = 0; j <= 2; j++) {
      int n = min(2, i + j);
      c.v[n] = add(c.v[n], mult(a.v[i], b.v[j]));
    }
  }
  return c;
}

trip comp(trip a) { return trip(add(a.v[0], a.v[2]), a.v[1], 0); }

void print(trip a) { cout << a.v[0] << " " << a.v[1] << " " << a.v[2] << endl; }

vector<trip> dp[MAX];
int ct[MAX];
void dfs(int u) {
  dep[u] = 1;
  int maxd = -1;
  int id = 0;
  for (int i : g[u]) {
    d[i] = d[u] + 1;
    dfs(i);
    dep[u] = max(dep[u], dep[i] + 1);
    if (dep[i] > maxd) {
      maxd = dep[i];
      id = i;
    }
  }

  int maxsz = 0;
  for (int i : g[u]) {
    if (i == id) {
      continue;
    }
    maxsz = max(maxsz, (int)dp[i].size());
    // merge i with id
    for (int j = 0; j < dp[i].size(); j++) {
      int offset = (int)dp[id].size() - (int)dp[i].size();
      // dp[i][k]
      // the depth number is dp[i].size() - 1 - k
      // so dp[u].size() - dp[i].size() + k

      dp[id][j + offset] = comb(dp[id][j + offset], dp[i][j]);
    }
  }
  swap(dp[u], dp[id]);

  for (int i = 1; i <= maxsz; i++) {
    dp[u][dp[u].size() - i] = comp(dp[u][dp[u].size() - i]);
  }
  dp[u].push_back(trip(inv(2), inv(2), 0));
}

int main() {
  // freopen("a.in", "r", stdin);

  pow2[0] = 1;
  for (int i = 1; i < MAX; i++) {
    pow2[i] = (pow2[i - 1] * 2) % MOD;
  }
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int p;
    scanf("%d", &p);
    g[p].push_back(i);
  }
  d[0] = 1;
  dfs(0);
  for (int i = 0; i <= n; i++) {
    ct[d[i]]++;
  }
  reverse(dp[0].begin(), dp[0].end());
  int ans = 0;
  for (int i = 0; i < dp[0].size(); i++) {
    ans = add(ans, mult(pow2[n + 1], dp[0][i].v[1]));
  }
  printf("%d\n", ans);
  /*
  d[0] = 1;
  dfs(0);
  for (int i=1; i<=n+1; i++) {
          process(n, i);
  }
  printf("%d\n", ans);
  */
}