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

#include <algorithm>
#include <bitset>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stdint.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ldouble = long double;

#define repi(i, a, b) for (ll i = (a); i < (b); i++)
#define rep(i, n) for (ll i = 0; i < (n); ++i)

const ll MAX = 510000;
const ll MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

using P = pair<int, ll>;
struct node {
  vector<int> link;
  int mattanp;
};

vector<node> nod;
unordered_map<ull, P> mem;

P f(int ind, int parent) {
  ull skey;
  if (parent != -1) {
    skey = ind;
    skey <<= 32;
    skey |= parent;
    if (mem.find(skey) != mem.end())
      return mem[skey];
  }
  vector<P> ps;
  for (int i : nod[ind].link)
    if (i != parent)
      ps.push_back(f(i, ind));
  int cc = 0;
  ll ret = 1;
  for (int i = 0; i < ps.size(); ++i)
    cc += ps[i].first;
  int cur = cc;
  for (int i = 0; i < ps.size(); ++i) {
    ret *= COM(cur, ps[i].first);
    cur -= ps[i].first;
    ret %= MOD;
    ret *= ps[i].second;
    ret %= MOD;
  }
  P r = P(cc + 1, ret);
  if (parent != -1)
    mem.insert(pair<ull, P>(skey, r));
  return r;
}

int main() {
  COMinit();
  int n;
  cin >> n;
  nod.resize(n);
  rep(i, n - 1) {
    int a, b;
    cin >> a >> b;
    nod[a - 1].link.push_back(b - 1);
    nod[b - 1].link.push_back(a - 1);
  }
  vector<ll> res(n);
  unordered_map<int, vector<int>> mp;
  rep(i, n) {
    if (nod[i].link.size() == 1) {
      nod[i].mattanp = nod[i].link[0];
      mp[nod[i].mattanp].push_back(i);
    } else
      nod[i].mattanp = -1;
  }
  for (auto itr = mp.begin(); itr != mp.end(); ++itr) {
    ll val = f(itr->second[0], -1).second;
    for (int i = 0; i < itr->second.size(); ++i)
      res[itr->second[i]] = val;
  }
  rep(i, n) if (nod[i].mattanp == -1) res[i] = f(i, -1).second;
  rep(i, n) cout << res[i] << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stdint.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ldouble = long double;

#define repi(i, a, b) for (ll i = (a); i < (b); i++)
#define rep(i, n) for (ll i = 0; i < (n); ++i)

const ll MAX = 510000;
const ll MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

using P = pair<int, ll>;
struct node {
  vector<int> link;
};

vector<node> nod;
unordered_map<ull, P> mem;

P f(int ind, int parent) {
  ull skey;
  if (parent != -1) {
    skey = ind;
    skey <<= 32;
    skey |= parent;
    if (mem.find(skey) != mem.end())
      return mem[skey];
  }
  vector<P> ps;
  for (int i : nod[ind].link)
    if (i != parent)
      ps.push_back(f(i, ind));
  int cc = 0;
  ll ret = 1;
  for (int i = 0; i < ps.size(); ++i)
    cc += ps[i].first;
  int cur = cc;
  for (int i = 0; i < ps.size(); ++i) {
    ret *= COM(cur, ps[i].first);
    cur -= ps[i].first;
    ret %= MOD;
    ret *= ps[i].second;
    ret %= MOD;
  }
  P r = P(cc + 1, ret);
  if (parent != -1)
    mem.insert(pair<ull, P>(skey, r));
  return r;
}

int main() {
  COMinit();
  int n;
  cin >> n;
  nod.resize(n);
  rep(i, n - 1) {
    int a, b;
    cin >> a >> b;
    nod[a - 1].link.push_back(b - 1);
    nod[b - 1].link.push_back(a - 1);
  }
  rep(i, n) { cout << f(i, -1).second << endl; }
  return 0;
}