Problem p03499 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int n, a[200009], cnt, id[200009], res[200009], mod = 1000000007;
vector<int> x[200009];
vector<pair<long long, long long>> lis[2000009];

long long modpow(long long a, long long b, long long m) {
  long long p = 1, q = a;
  for (int i = 0; i < 32; i++) {
    if ((b & (1LL << i)) != 0) {
      p *= q;
      p %= m;
    }
    q *= q;
    q %= m;
  }
  return p;
}
long long Div(long long a, long long b, long long m) {
  return (a * modpow(b, m - 2, m)) % m;
}

void dfs(int pos, int depth) {
  res[depth]++;
  if (x[pos].size() == 0) {
    cnt++;
    id[pos] = cnt;
    lis[cnt].push_back(make_pair(1, 1));
    return;
  }
  for (int i = 0; i < x[pos].size(); i++)
    dfs(x[pos][i], depth + 1);
  vector<pair<long long, long long>> V;
  for (int i : x[pos]) {
    V.push_back(make_pair(lis[id[i]].size(), i));
  }
  sort(V.begin(), V.end());
  if (V.size() == 1) {
    id[pos] = id[V[V.size() - 1].second];
    lis[id[pos]].push_back(make_pair(1, 1));
    return;
  }
  for (int i = 0; i < V[V.size() - 2].first; i++) {
    int pos1 =
        lower_bound(V.begin(), V.end(), make_pair((long long)(i + 1), 0LL)) -
        V.begin();

    long long product = 1, sum = 0, sum2 = 1;
    for (int j = pos1; j < V.size(); j++) {
      int ID = id[V[j].second];
      product *= lis[ID][lis[ID].size() - i - 1].second;
      product %= mod;
      sum2 *= (lis[ID][lis[ID].size() - i - 1].first +
               lis[ID][lis[ID].size() - i - 1].second);
      sum2 %= mod;
    }
    for (int j = pos1; j < V.size(); j++) {
      int ID = id[V[j].second];
      long long a = lis[ID][lis[ID].size() - i - 1].first;
      long long b = lis[ID][lis[ID].size() - i - 1].second;
      long long I = Div(product, b, mod) * a;
      I %= mod;
      sum += I;
    }
    sum %= mod;
    int ID = id[V[V.size() - 1].second];
    lis[ID][lis[ID].size() - i - 1] = make_pair(sum, (sum2 - sum + mod) % mod);
  }
  id[pos] = id[V[V.size() - 1].second];
  lis[id[pos]].push_back(make_pair(1, 1));
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    x[a[i]].push_back(i);
  }
  dfs(0, 0);
  long long finalans = 0;
  for (int i = 0; i < lis[id[0]].size(); i++) {
    long long a1 = lis[id[0]][i].first;
    long long a2 = lis[id[0]][i].second;
    long long depth = lis[id[0]].size() - i - 1;
    while ((a1 + a2) != modpow(2, res[depth], mod)) {
      a1 *= 2;
      a2 *= 2;
      a1 %= mod;
      a2 %= mod;
    }
    a1 *= modpow(2, n + 1 - res[depth], mod);
    a1 %= mod;
    a2 *= modpow(2, n + 1 - res[depth], mod);
    a2 %= mod;
    finalans += a1;
    finalans %= mod;
  }
  cout << finalans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int n, a[200009], cnt, id[200009], res[200009], mod = 1000000007;
vector<int> x[200009];
vector<pair<long long, long long>> lis[2000009];

long long modpow(long long a, long long b, long long m) {
  long long p = 1, q = a;
  for (int i = 0; i < 32; i++) {
    if ((b & (1LL << i)) != 0) {
      p *= q;
      p %= m;
    }
    q *= q;
    q %= m;
  }
  return p;
}
long long Div(long long a, long long b, long long m) {
  return (a * modpow(b, m - 2, m)) % m;
}

void dfs(int pos, int depth) {
  res[depth]++;
  if (x[pos].size() == 0) {
    cnt++;
    id[pos] = cnt;
    lis[cnt].push_back(make_pair(1, 1));
    return;
  }
  for (int i = 0; i < x[pos].size(); i++)
    dfs(x[pos][i], depth + 1);
  vector<pair<long long, long long>> V;
  for (int i : x[pos]) {
    V.push_back(make_pair(lis[id[i]].size(), i));
  }
  sort(V.begin(), V.end());
  if (V.size() == 1) {
    id[pos] = id[V[V.size() - 1].second];
    lis[id[pos]].push_back(make_pair(1, 1));
    return;
  }
  for (int i = 0; i < V[V.size() - 2].first; i++) {
    int pos1 =
        lower_bound(V.begin(), V.end(), make_pair((long long)(i + 1), 0LL)) -
        V.begin();

    long long product = 1, sum = 0, sum2 = 1;
    for (int j = pos1; j < V.size(); j++) {
      int ID = id[V[j].second];
      product *= lis[ID][lis[ID].size() - i - 1].second;
      product %= mod;
      sum2 *= (lis[ID][lis[ID].size() - i - 1].first +
               lis[ID][lis[ID].size() - i - 1].second);
      sum2 %= mod;
    }
    for (int j = pos1; j < V.size(); j++) {
      int ID = id[V[j].second];
      long long a = lis[ID][lis[ID].size() - i - 1].first;
      long long b = lis[ID][lis[ID].size() - i - 1].second;
      long long I = Div(product, b, mod) * a;
      I %= mod;
      sum += I;
    }
    sum %= mod;
    int ID = id[V[V.size() - 1].second];
    lis[ID][lis[ID].size() - i - 1] = make_pair(sum, (sum2 - sum + mod) % mod);
  }
  id[pos] = id[V[V.size() - 1].second];
  lis[id[pos]].push_back(make_pair(1, 1));
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    x[a[i]].push_back(i);
  }
  dfs(0, 0);
  long long finalans = 0;
  for (int i = 0; i < lis[id[0]].size(); i++) {
    long long a1 = lis[id[0]][i].first;
    long long a2 = lis[id[0]][i].second;
    long long depth = lis[id[0]].size() - i - 1;
    while ((a1 + a2) % mod != modpow(2, res[depth], mod)) {
      a1 *= 2;
      a2 *= 2;
      a1 %= mod;
      a2 %= mod;
    }
    a1 *= modpow(2, n + 1 - res[depth], mod);
    a1 %= mod;
    a2 *= modpow(2, n + 1 - res[depth], mod);
    a2 %= mod;
    finalans += a1;
    finalans %= mod;
  }
  cout << finalans << endl;
  return 0;
}