Problem p01723 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;
const ll M = 1000000007;

ll modpow(ll x, ll k) {
  if (k == 0)
    return 1;
  ll ret = modpow(x, k / 2);
  ret *= ret;
  ret %= M;
  if (k % 2 == 1) {
    ret *= x;
    ret %= M;
  }
  return ret;
}

ll fac[602], fac_inv[602];
void fac_init() {
  fac[0] = 1;
  for (int i = 1; i <= 600; i++) {
    fac[i] = fac[i - 1] * i;
    fac[i] %= M;
  }
  for (int i = 0; i <= 600; i++) {
    fac_inv[i] = modpow(fac[i], M - 2);
  }
}

ll f(int x, int y, int z) {
  if (z < x || z < y || z > x + y)
    return 0;
  if (x == 0)
    return (y == z) ? 1 : 0;
  if (y == 0)
    return (x == z) ? 1 : 0;
  ll ret = 1;
  ret *= fac[z];
  ret *= fac_inv[z - x];
  ret %= M;
  ret *= fac_inv[z - y];
  ret %= M;
  ret *= fac_inv[x + y - z];
  ret %= M;
  return ret;
}

ll ans[202][202];
int siz[202];
vector<int> ch[202];
void dfs(int v) {
  for (int i = 0; i < ch[v].size(); i++) {
    dfs(ch[v][i]);
    siz[v] += siz[ch[v][i]];
    for (int j = siz[v]; j >= 0; j--) {
      ll sum = 0;
      for (int k = 0; k <= j; k++)
        for (int l = 0; l <= j; l++) {
          sum += (ans[v][k] * ans[ch[v][i]][l]) % M * f(k, l, j);
          sum %= M;
        }
      ans[v][j] = sum;
    }
  }
  for (int i = 201; i > 0; i--) {
    ans[v][i] = ans[v][i - 1];
  }
  ans[v][0] = 0;
  siz[v]++;
}

int main() {
  fac_init();
  int n;
  int a[202], b[202];

  scanf("%d", &n);
  for (int i = 0; i < n - 1; i++) {
    scanf("%d%d", &a[i], &b[i]);
    ch[a[i]].push_back(b[i]);
  }
  for (int i = 0; i < 202; i++) {
    for (int j = 0; j < 202; j++) {
      ans[i][j] = 0;
    }
    ans[i][0] = 1;
    siz[i] = 0;
  }

  int cnt[202] = {};
  for (int i = 0; i < n - 1; i++) {
    cnt[b[i]]++;
  }
  for (int i = 0; i < n; i++) {
    if (cnt[i] == 0) {
      dfs(i);
      ll ret = 0;
      for (int j = 0; j <= n; j++) {
        ret += ans[i][j];
      }
      cout << ret % M << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;
const ll M = 1000000009;

ll modpow(ll x, ll k) {
  if (k == 0)
    return 1;
  ll ret = modpow(x, k / 2);
  ret *= ret;
  ret %= M;
  if (k % 2 == 1) {
    ret *= x;
    ret %= M;
  }
  return ret;
}

ll fac[602], fac_inv[602];
void fac_init() {
  fac[0] = 1;
  for (int i = 1; i <= 600; i++) {
    fac[i] = fac[i - 1] * i;
    fac[i] %= M;
  }
  for (int i = 0; i <= 600; i++) {
    fac_inv[i] = modpow(fac[i], M - 2);
  }
}

ll f(int x, int y, int z) {
  if (z < x || z < y || z > x + y)
    return 0;
  if (x == 0)
    return (y == z) ? 1 : 0;
  if (y == 0)
    return (x == z) ? 1 : 0;
  ll ret = 1;
  ret *= fac[z];
  ret *= fac_inv[z - x];
  ret %= M;
  ret *= fac_inv[z - y];
  ret %= M;
  ret *= fac_inv[x + y - z];
  ret %= M;
  return ret;
}

ll ans[202][202];
vector<int> ch[202];
void dfs(int v) {
  for (int i = 0; i < ch[v].size(); i++) {
    dfs(ch[v][i]);
    for (int j = 200; j >= 0; j--) {
      ll sum = 0;
      for (int k = 0; k <= j; k++)
        for (int l = 0; l <= j; l++) {
          sum += (ans[v][k] * ans[ch[v][i]][l]) % M * f(k, l, j);
          sum %= M;
        }
      ans[v][j] = sum;
    }
  }
  for (int i = 201; i > 0; i--) {
    ans[v][i] = ans[v][i - 1];
  }
  ans[v][0] = 0;
}

int main() {
  fac_init();
  int n;
  int a[202], b[202];

  scanf("%d", &n);
  for (int i = 0; i < n - 1; i++) {
    scanf("%d%d", &a[i], &b[i]);
    ch[a[i]].push_back(b[i]);
  }
  for (int i = 0; i < 202; i++) {
    for (int j = 0; j < 202; j++) {
      ans[i][j] = 0;
    }
    ans[i][0] = 1;
  }

  int cnt[202] = {};
  for (int i = 0; i < n - 1; i++) {
    cnt[b[i]]++;
  }
  for (int i = 0; i < n; i++) {
    if (cnt[i] == 0) {
      dfs(i);
      ll ret = 0;
      for (int j = 0; j <= n; j++) {
        ret += ans[i][j];
      }
      cout << ret % M << endl;
    }
  }
}