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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 200010, M = 1e9 + 7;
ll hd[N], to[N << 1], nxt[N << 1], siz[N], son[N];
ll in[N], jc[N], jcin[N];
ll tot, n;
ll ans[N], met[N], up[N];
void add(ll x, ll y) {
  to[++tot] = y;
  nxt[tot] = hd[x];
  hd[x] = tot;
}
ll dfs(ll x, ll f) {
  ll t = 1;
  siz[x] = 1;
  son[x] = 0;
  for (ll i = hd[x]; i; i = nxt[i]) {
    if (to[i] != f) {
      t *= dfs(to[i], x);
      t %= M;
      siz[x] += siz[to[i]];
      ++son[x];
    }
  }
  t *= jc[siz[x] - 1];
  t %= M;
  for (ll i = hd[x]; i; i = nxt[i]) {
    if (to[i] != f) {
      t *= jcin[siz[to[i]]];
      t %= M;
    }
  }
  met[x] = t;
  return t;
}
void exgcd(ll a, ll b, ll &x, ll &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return;
  }
  exgcd(b, a % b, y, x);
  y -= a / b * x;
}
ll inv(ll p) {
  if (p <= n)
    return in[p];
  ll x = 0, y = 0;
  exgcd(M, p, x, y);
  if (y > 0)
    return y % M;
  return (M + (y % M));
}
void work(ll x, ll f) {
  if (!f) {
    for (ll i = hd[x]; i; i = nxt[i]) {
      ll j = to[i];
      up[j] = met[1];
      up[j] *= inv(met[j]);
      up[j] %= M;
      up[j] *= jc[siz[j]];
      up[j] %= M;
      up[j] *= jcin[n - 1];
      up[j] %= M;
      up[j] *= jc[n - siz[j] - 1];
      up[j] %= M;
      // printf("up[%lld]=%lld\\n",j,up[j]);
      work(j, x);
    }
  } else {
    ll t = up[x];
    t *= jcin[n - siz[x]];
    t %= M;
    // printf("1x=%lld,t=%lld\\n",x,t);
    for (ll i = hd[x]; i; i = nxt[i]) {
      if (to[i] != f) {
        t *= jcin[siz[to[i]]];
        t %= M;
        t *= met[to[i]];
        t %= M;
      }
    }
    // printf("2x=%lld,t=%lld\\n",x,t);
    for (ll i = hd[x]; i; i = nxt[i]) {
      if (to[i] != f) {
        ll j = to[i];
        up[j] = t;
        up[j] *= inv(met[j]);
        up[j] %= M;
        up[j] *= jc[n - siz[j] - 1];
        up[j] %= M;
        up[j] *= jc[siz[j]];
        up[j] %= M;
        work(j, x);
      }
    }
  }
}
void sol(ll x, ll f) {
  if (!f) {
    for (ll i = hd[x]; i; i = nxt[i])
      sol(to[i], x);
    return;
  }
  ans[x] = jc[n - 1];
  for (ll i = hd[x]; i; i = nxt[i]) {
    if (to[i] != f) {
      ll j = to[i];
      sol(j, x);
      ans[x] *= met[j];
      ans[x] %= M;
      ans[x] *= jcin[siz[j]];
      ans[x] %= M;
    }
  }
  ans[x] *= up[x];
  ans[x] %= M;
  ans[x] *= jcin[n - siz[x]];
  ans[x] %= M;
}
int main() {
  // freopen("F.txt","r",stdin);
  scanf("%lld", &n);
  for (ll i = 1; i < n; ++i) {
    ll x, y;
    scanf("%lld%lld", &x, &y);
    add(x, y);
    add(y, x);
  }
  jc[0] = jcin[0] = 1;
  jc[1] = jcin[1] = in[1] = 1;
  for (ll i = 2; i <= n; ++i) {
    jc[i] = jc[i - 1] * i % M;
    in[i] = in[M % i] * (M - M / i) % M;
    jcin[i] = jcin[i - 1] * in[i] % M;
  }
  dfs(1, 0);
  up[1] = 1;
  work(1, 0);
  sol(1, 0);
  ans[1] = met[1];
  // for(ll i=1;i<=n;++i) printf("met[%lld]=%lld\\n",i,met[i]);
  // for(ll i=1;i<=n;++i) printf("up[%lld]=%lld\\n",i,up[i]);
  // for(ll i=1;i<=n;++i)
  // printf("inv(%lld)=%lld,in[%lld]=%lld\\n",i+n,inv(i+n),i,in[i]);
  for (ll i = 1; i <= n; ++i) {
    printf("%lld\\n", ans[i]);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 200010, M = 1e9 + 7;
ll hd[N], to[N << 1], nxt[N << 1], siz[N], son[N];
ll in[N], jc[N], jcin[N];
ll tot, n;
ll ans[N], met[N], up[N];
void add(ll x, ll y) {
  to[++tot] = y;
  nxt[tot] = hd[x];
  hd[x] = tot;
}
ll dfs(ll x, ll f) {
  ll t = 1;
  siz[x] = 1;
  son[x] = 0;
  for (ll i = hd[x]; i; i = nxt[i]) {
    if (to[i] != f) {
      t *= dfs(to[i], x);
      t %= M;
      siz[x] += siz[to[i]];
      ++son[x];
    }
  }
  t *= jc[siz[x] - 1];
  t %= M;
  for (ll i = hd[x]; i; i = nxt[i]) {
    if (to[i] != f) {
      t *= jcin[siz[to[i]]];
      t %= M;
    }
  }
  met[x] = t;
  return t;
}
void exgcd(ll a, ll b, ll &x, ll &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return;
  }
  exgcd(b, a % b, y, x);
  y -= a / b * x;
}
ll inv(ll p) {
  if (p <= n)
    return in[p];
  ll x = 0, y = 0;
  exgcd(M, p, x, y);
  if (x > 0)
    return x % M;
  return (M - (x % M));
}
void work(ll x, ll f) {
  ll t = up[f];
  t *= jcin[n - siz[x]];
  t %= M;
  for (ll i = hd[x]; i; i = nxt[i]) {
    if (to[i] != f) {
      t *= jcin[siz[to[i]]];
      t %= M;
      t *= met[to[i]];
      t %= M;
    }
  }
  for (ll i = hd[x]; i; i = nxt[i]) {
    if (to[i] != f) {
      ll j = to[i];
      up[j] = t;
      up[j] *= inv(met[j]);
      up[j] %= M;
      up[j] *= n - siz[j] - 1;
      up[j] %= M;
      up[j] *= jc[siz[j]];
      up[j] %= M;
    }
  }
}
int main() {
  scanf("%lld", &n);
  for (ll i = 1; i < n; ++i) {
    ll x, y;
    scanf("%lld%lld", &x, &y);
    add(x, y);
    add(y, x);
  }
  jc[0] = jcin[0] = 1;
  jc[1] = jcin[1] = in[1] = 1;
  for (ll i = 2; i <= n; ++i) {
    jc[i] = jc[i - 1] * i % M;
    in[i] = in[M % i] * (M - M / i) % M;
    jcin[i] = jcin[i - 1] * in[i] % M;
  }
  dfs(1, 0);
  up[0] = 1;
  work(1, 0);
  for (ll i = 1; i <= n; ++i) {
    printf("%lld\\n", dfs(i, 0));
  }
  return 0;
}