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

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9 + 7;

int n, st = 1, tot = 1, cnt = 0;
int head[500005], size[200005], ans[200005];

struct edge {
  int next;
  int to;
} e[500005];

int quick_power(int a, int b) {
  if (b == 0)
    return 1;

  int res = 1;
  for (; b; b = b >> 1, a = (a * a) % mod) {
    if (b & 1)
      res = (res * a) % mod;
  }
  return res;
}

int ny(int k) { return quick_power(k, mod - 2) % mod; }

int divide(int a, int b) { return (a * ny(b)) % mod; }

inline void add_edge(int u, int v) {
  cnt++;
  e[cnt].to = v;
  e[cnt].next = head[u];
  head[u] = cnt;
}

inline void dfs(int now, int fath) {
  size[now] = 1;
  for (int i = head[now]; i; i = e[i].next) {
    if (e[i].to != fath) {
      dfs(e[i].to, now);
      size[now] += size[e[i].to];
    }
  }
}

inline void change_root(int now, int last) {
  if (last == 0) {
    ans[now] = divide(tot, st) % mod;
    for (int i = head[now]; i; i = e[i].next) {
      if (e[i].to != last)
        change_root(e[i].to, now);
    }
  } else {
    int x = size[now], y = size[last];
    st = divide(st, size[now]) % mod;
    st = divide(st, size[last]) % mod;
    size[last] -= size[now];
    size[now] += size[last];
    st = (st * size[now]) % mod;
    st = (st * size[last]) % mod;

    ans[now] = divide(tot, st);

    for (int i = head[now]; i; i = e[i].next) {
      if (e[i].to != last)
        change_root(e[i].to, now);
    }
    st = divide(st, size[last]) % mod;
    st = divide(st, size[now]) % mod;
    st = (st * y) % mod;
    st = (st * x) % mod;
    size[now] = x;
    size[last] = y;
  }
}

signed main() {
  cin >> n;
  for (int i = 1; i <= n; i++)
    tot = (tot * i) % mod;
  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    add_edge(u, v);
    add_edge(v, u);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; i++)
    st = (st * size[i]) % mod;

  change_root(1, 0);
  for (int i = 1; i <= n; i++)
    cout << ans[i] % mod << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9 + 7;

int n, st = 1, tot = 1, cnt = 0;
int head[500005], size[200005], ans[200005];

struct edge {
  int next;
  int to;
} e[500005];

int quick_power(int a, int b) {
  if (b == 0)
    return 1;

  int res = 1;
  for (; b; b = b >> 1, a = (a * a) % mod) {
    if (b & 1)
      res = (res * a) % mod;
  }
  return res;
}

int ny(int k) { return quick_power(k, mod - 2) % mod; }

int divide(int a, int b) { return (a * ny(b)) % mod; }

inline void add_edge(int u, int v) {
  cnt++;
  e[cnt].to = v;
  e[cnt].next = head[u];
  head[u] = cnt;
}

inline void dfs(int now, int fath) {
  size[now] = 1;
  for (int i = head[now]; i; i = e[i].next) {
    if (e[i].to != fath) {
      dfs(e[i].to, now);
      size[now] += size[e[i].to];
    }
  }
}

inline void change_root(int now, int last) {
  if (last == 0) {
    ans[now] = divide(tot, st) % mod;
    for (int i = head[now]; i; i = e[i].next) {
      if (e[i].to != last)
        change_root(e[i].to, now);
    }
  } else {
    int x = size[now], y = size[last], all = 1;
    st = divide(st, size[now]);
    st = divide(st, size[last]);
    size[last] -= size[now];
    size[now] += size[last];
    st = (st * size[now]) % mod;
    st = (st * size[last]) % mod;

    for (int i = 1; i <= n; i++)
      all = (all * size[i]) % mod;
    ans[now] = divide(tot, all);

    for (int i = head[now]; i; i = e[i].next) {
      if (e[i].to != last)
        change_root(e[i].to, now);
    }
    size[now] = x;
    size[last] = y;
    st = divide(st, size[last]) % mod;
    st = divide(st, size[now]) % mod;
    st = (st * y) % mod;
    st = (st * x) % mod;
  }
}

signed main() {
  cin >> n;
  for (int i = 1; i <= n; i++)
    tot = tot * i;
  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    add_edge(u, v);
    add_edge(v, u);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; i++)
    st *= size[i];

  change_root(1, 0);
  for (int i = 1; i <= n; i++)
    cout << ans[i] << endl;

  return 0;
}