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

#include <iostream>
#include <map>
#include <vector>

using namespace std;

long long int MOD = 1000000007;

int N, a[200005], b[200005];

vector<int> Adj[200005];

long long int dp[200005];

long long int p[200005], p_inv[200005];
int used[200005];
int num_child[200005];

map<pair<int, int>, long long int> memo;
map<pair<int, int>, int> NC;

long long int POW(long long int a, long long int k) {
  if (k == 0) {
    return 1;
  }
  if (k % 2 == 1) {
    return (POW(a, k - 1) * a) % MOD;
  }
  long long int tmp = POW(a, k / 2);

  return (tmp * tmp) % MOD;
}

long long int INV(long long int a) { return POW(a, MOD - 2); }

long long int CALL(int par, int u) {

  if (memo[make_pair(par, u)] > 0) {
    return memo[make_pair(par, u)];
  }

  // cout << "call" << endl;

  long long int ret = 1;
  int num_c = 0;
  for (auto y : Adj[u]) {
    if (y == par) {
      continue;
    }
    ret *= CALL(u, y);
    ret %= MOD;
    num_c += NC[make_pair(u, y)];
    ret *= p_inv[NC[make_pair(u, y)]];
    ret %= MOD;
    // cout << "ret= " << ret << endl;
  }

  // cout << "num_child= " << num_child[u] << endl;
  ret *= p[num_c];
  ret %= MOD;

  memo[make_pair(par, u)] = ret;
  NC[make_pair(par, u)] = num_c + 1;

  return ret;
}

void PROC(int par, int u) {

  long long int val = memo[make_pair(0, par)];

  int num_c = NC[make_pair(par, u)];

  val *= INV(p[N - 1]);
  val %= MOD;
  val *= p[num_c];
  val %= MOD;
  val *= INV(memo[make_pair(par, u)]);
  val %= MOD;

  NC[make_pair(u, par)] = N - num_c;

  val *= p[N - 1 - num_c];
  val %= MOD;

  memo[make_pair(u, par)] = val;

  long long int wal = memo[make_pair(par, u)];

  // cout << "wal= " << wal << endl;
  wal *= INV(p[num_c - 1]);
  wal %= MOD;
  wal *= INV(p[N - num_c]);
  wal %= MOD;
  wal *= p[N - 1];
  wal %= MOD;
  wal *= memo[make_pair(u, par)];
  wal %= MOD;
  memo[make_pair(0, u)] = wal;

  for (auto y : Adj[u]) {
    if (y != par) {
      PROC(u, y);
    }
  }
}

int main(void) {

  cin >> N;
  for (int i = 1; i <= N - 1; i++) {
    cin >> a[i] >> b[i];
    Adj[a[i]].push_back(b[i]);
    Adj[b[i]].push_back(a[i]);
    NC[make_pair(a[i], b[i])] = -1;
    NC[make_pair(b[i], a[i])] = -1;
  }

  p[0] = 1;
  for (long long int i = 1; i <= N; i++) {
    p[i] = p[i - 1] * i;
    p[i] %= MOD;
    p_inv[i] = INV(p[i]);
  }

  /*cout << CALL(-1, 2) << endl;

  cout << NC[make_pair(-1, 2)] << endl;
  cout << NC[make_pair(2, 1)] << endl;
  cout << memo[make_pair(2, 1)] << endl;
  cout << memo[make_pair(1, 3)] << endl;
  */

  CALL(0, 1);

  for (auto y : Adj[1]) {
    PROC(1, y);
  }

  for (int i = 1; i <= N; i++) {
    cout << memo[make_pair(0, i)] << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <map>
#include <vector>

using namespace std;

long long int MOD = 1000000007;

int N, a[200005], b[200005];

vector<int> Adj[200005];

long long int dp[200005];

long long int p[200005], p_inv[200005];
int used[200005];
int num_child[200005];

map<pair<int, int>, long long int> memo;
map<pair<int, int>, int> NC;

long long int POW(long long int a, long long int k) {
  if (k == 0) {
    return 1;
  }
  if (k % 2 == 1) {
    return (POW(a, k - 1) * a) % MOD;
  }
  long long int tmp = POW(a, k / 2);

  return (tmp * tmp) % MOD;
}

long long int INV(long long int a) { return POW(a, MOD - 2); }

long long int CALL(int par, int u) {

  if (memo[make_pair(par, u)] > 0) {
    return memo[make_pair(par, u)];
  }

  long long int ret = 1;
  int num_c = 0;
  for (auto y : Adj[u]) {
    if (y == par) {
      continue;
    }
    ret *= CALL(u, y);
    ret %= MOD;
    num_c += NC[make_pair(u, y)];
    ret *= p_inv[NC[make_pair(u, y)]];
    ret %= MOD;
    // cout << "ret= " << ret << endl;
  }

  // cout << "num_child= " << num_child[u] << endl;
  ret *= p[num_c];
  ret %= MOD;

  memo[make_pair(par, u)] = ret;
  NC[make_pair(par, u)] = num_c + 1;

  return ret;
}

int main(void) {

  cin >> N;
  for (int i = 1; i <= N - 1; i++) {
    cin >> a[i] >> b[i];
    Adj[a[i]].push_back(b[i]);
    Adj[b[i]].push_back(a[i]);
    NC[make_pair(a[i], b[i])] = -1;
    NC[make_pair(b[i], a[i])] = -1;
  }

  p[0] = 1;
  for (long long int i = 1; i <= N; i++) {
    p[i] = p[i - 1] * i;
    p[i] %= MOD;
    p_inv[i] = INV(p[i]);
  }

  /*cout << CALL(-1, 2) << endl;

  cout << NC[make_pair(-1, 2)] << endl;
  cout << NC[make_pair(2, 1)] << endl;
  cout << memo[make_pair(2, 1)] << endl;
  cout << memo[make_pair(1, 3)] << endl;
  */
  for (int i = 1; i <= N; i++) {
    // for (int k = 1; k <= N; k++) { dp[k] = 0; used[k] = 0; num_child[k] = 0;
    // }
    cout << CALL(-1, i) << endl;
  }

  return 0;
}