Problem p02822 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

template <typename t> void myMemset(t *arr, t val, unsigned int size) {
  size /= sizeof(t);
  t *ptr = arr;
  while (size--) {
    *ptr = val;
    ptr++;
  }
}

const int mod = 1e9 + 7;

int add(int a, int b) { return (a + b) % mod; }

int mul(int a, int b) { return (1ll * a * b) % mod; }

int fastpow(int b, int p) {
  if (!p)
    return 1;
  int ret = fastpow(b, p / 2);
  ret = mul(ret, ret);
  if (p & 1)
    ret = mul(ret, b);
  return ret;
}

const int N = 2e5 + 5;
vector<int> g[N];
vector<int> szs[N];
int n, sz[N];

void dfs(int node, int parent = -1) {
  sz[node] = 1;
  for (auto &neg : g[node])
    if (neg != parent)
      dfs(neg, node), sz[node] += sz[neg], szs[node].push_back(sz[neg]);
  if (n - sz[node] >= 1)
    szs[node].push_back(n - sz[node]);
}

int dp[N];
int dp2[N][3];
int val[N];
int mark[N][3], half;

int solve2(int sz) {
  if (sz == 0)
    return 0;
  int &ans = dp[sz];
  if (ans != -1)
    return ans;
  return ans = add(half, mul(half, solve2(sz - 1)));
}

int solve(int node, int idx, int cnt) {
  if (idx == szs[node].size())
    return cnt == 2;
  int &ans = dp2[idx][cnt];
  if (mark[idx][cnt] == node)
    return ans;
  mark[idx][cnt] = 1;
  return ans = add(mul(solve(node, idx + 1, cnt), val[szs[node][idx]]),
                   mul(solve(node, idx + 1, min(cnt + 1, 2)),
                       solve2(szs[node][idx])));
}

int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  half = fastpow(2, mod - 2);
  val[0] = 1;
  for (int i = 1; i < N; i++)
    val[i] = mul(val[i - 1], half);
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(1);
  int ans = 0;
  memset(dp, -1, sizeof dp);
  for (int i = 1; i <= n; i++)
    ans = add(ans, mul(half, solve(i, 0, 0)));
  cout << ans;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

template <typename t> void myMemset(t *arr, t val, unsigned int size) {
  size /= sizeof(t);
  t *ptr = arr;
  while (size--) {
    *ptr = val;
    ptr++;
  }
}

const int mod = 1e9 + 7;

int add(int a, int b) { return (a + b) % mod; }

int mul(int a, int b) { return (1ll * a * b) % mod; }

int fastpow(int b, int p) {
  if (!p)
    return 1;
  int ret = fastpow(b, p / 2);
  ret = mul(ret, ret);
  if (p & 1)
    ret = mul(ret, b);
  return ret;
}

const int N = 2e5 + 5;
vector<int> g[N];
vector<int> szs[N];
int n, sz[N];

void dfs(int node, int parent = -1) {
  sz[node] = 1;
  for (auto &neg : g[node])
    if (neg != parent)
      dfs(neg, node), sz[node] += sz[neg], szs[node].push_back(sz[neg]);
  if (n - sz[node] >= 1)
    szs[node].push_back(n - sz[node]);
}

int dp[N];
int dp2[N][3];
int val[N];
int mark[N][3], half;

int solve2(int sz) {
  if (sz == 0)
    return 0;
  int &ans = dp[sz];
  if (ans != -1)
    return ans;
  return ans = add(half, mul(half, solve2(sz - 1)));
}

int solve(int node, int idx, int cnt) {
  if (idx == szs[node].size())
    return cnt == 2;
  int &ans = dp2[idx][cnt];
  if (mark[idx][cnt] == node)
    return ans;
  mark[idx][cnt] = node;
  return ans = add(mul(solve(node, idx + 1, cnt), val[szs[node][idx]]),
                   mul(solve(node, idx + 1, min(cnt + 1, 2)),
                       solve2(szs[node][idx])));
}

int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  half = fastpow(2, mod - 2);
  val[0] = 1;
  for (int i = 1; i < N; i++)
    val[i] = mul(val[i - 1], half);
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(1);
  int ans = 0;
  memset(dp, -1, sizeof dp);
  for (int i = 1; i <= n; i++)
    ans = add(ans, mul(half, solve(i, 0, 0)));
  cout << ans;
  return 0;
}