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

#include <bits/stdc++.h>
#define ll long long
#define M 1000000007
#define MAX_SIZE 200005
using namespace std;

vector<ll> fac(MAX_SIZE);  // n!(mod M)
vector<ll> ifac(MAX_SIZE); // k!^{M-2} (mod M)

ll mpow(ll x,
        ll n) { // x^n(mod M) ←普通にpow(x,n)では溢れてしまうため，随時mod計算
  ll ans = 1;
  while (n != 0) {
    if (n & 1)
      ans = ans * x % M;
    x = x * x % M;
    n = n >> 1; // n = n/2
  }
  return ans;
}
void init_comb() {
  fac[0] = 1;
  ifac[0] = 1;
  for (ll i = 1; i < MAX_SIZE; i++) {
    fac[i] = fac[i - 1] * i % M;                // n!(mod M)
    ifac[i] = ifac[i - 1] * mpow(i, M - 2) % M; // k!^{M-2} (mod M)
  }
}
ll combination(ll n, ll m) {
  if (m == n || m == 0)
    return 1;
  ll tmp = fac[n] * ifac[m] % M;
  return tmp * ifac[n - m] % M;
}
ll mdev(ll a, ll b) { return a * mpow(b, M - 2) % M; }

struct Info {
  ll cmb;
  ll t;
  Info(ll cmb = 1, ll t = 0) : cmb(cmb), t(t) {}
  Info operator+(Info a) {
    ll tmp_cmb = cmb * a.cmb % M;
    return Info(tmp_cmb * combination(t + a.t, t) % M, t + a.t);
  }
  Info operator-(Info a) {
    ll tmp_cmb = mdev(cmb, a.cmb);
    return Info(mdev(tmp_cmb, combination(t, t - a.t)), t - a.t);
    // return Info(tmp_cmb, t-a.t);
  }
  Info includeRoot() { return Info(cmb, t + 1); }
};

vector<ll> graph[MAX_SIZE];
Info infov[MAX_SIZE];

Info dfs(ll i, ll parent_i) {

  Info info;
  for (int j = 0; j < graph[i].size(); j++) {
    ll child_i = graph[i][j];
    if (child_i == parent_i)
      continue;
    info = info + dfs(child_i, i).includeRoot();
  }
  infov[i] = info;
  return info;
}

void reverse_dfs(ll i, ll parent_i) {
  if (parent_i >= 0) {
    Info rparent = infov[parent_i] - infov[i].includeRoot();
    infov[i] = infov[i] + rparent.includeRoot();
  }
  for (int j = 0; j < graph[i].size(); j++) {
    ll child_i = graph[i][j];
    if (child_i == parent_i)
      continue;
    reverse_dfs(child_i, i);
  }
}

int main() {
  init_comb();
  ll N, a, b;

  cin >> N;

  for (ll i = 0; i < N - 1; i++) {
    cin >> a >> b;
    a--;
    b--;
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  dfs(0, -1);
  reverse_dfs(0, -1);
  for (int k = 0; k < N; k++) {

    cout << infov[k].cmb << endl;
    // cout<<"----------------------"<<endl;
    // for(int i=0;i<N;i++){
    // 	cout<<" "<<infov[i].cmb<< " " << infov[i].t << endl;
    // }
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define ll long long
#define M 1000000007
#define MAX_SIZE 200005
using namespace std;

vector<ll> fac(MAX_SIZE);  // n!(mod M)
vector<ll> ifac(MAX_SIZE); // k!^{M-2} (mod M)

ll mpow(ll x,
        ll n) { // x^n(mod M) ←普通にpow(x,n)では溢れてしまうため，随時mod計算
  ll ans = 1;
  while (n != 0) {
    if (n & 1)
      ans = ans * x % M;
    x = x * x % M;
    n = n >> 1; // n = n/2
  }
  return ans;
}
void init_comb() {
  fac[0] = 1;
  ifac[0] = 1;
  for (ll i = 1; i < MAX_SIZE; i++) {
    fac[i] = fac[i - 1] * i % M;                // n!(mod M)
    ifac[i] = ifac[i - 1] * mpow(i, M - 2) % M; // k!^{M-2} (mod M)
  }
}
ll combination(ll n, ll m) {
  if (m == n || m == 0)
    return 1;
  ll tmp = fac[n] * ifac[m] % M;
  return tmp * ifac[n - m] % M;
}

struct Info {
  ll cmb;
  ll t;
  Info(ll cmb = 1, ll t = 0) : cmb(cmb), t(t) {}
  Info operator+(Info a) {
    ll tmp_cmb = cmb * a.cmb % M;
    return Info(tmp_cmb * combination(t + a.t, t) % M, t + a.t);
  }
};

vector<ll> graph[MAX_SIZE];
Info infov[MAX_SIZE];

Info dfs(ll i, ll parent_i) {

  Info info;
  for (int j = 0; j < graph[i].size(); j++) {
    ll child_i = graph[i][j];
    if (child_i == parent_i)
      continue;
    info = info + dfs(child_i, i);
  }
  info.t += 1;
  infov[i] = info;
  return info;
}

int main() {
  init_comb();
  ll N, a, b;

  cin >> N;

  for (ll i = 0; i < N - 1; i++) {
    cin >> a >> b;
    a--;
    b--;
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  for (int k = 0; k < N; k++) {
    Info ans = dfs(k, -1);
    cout << ans.cmb << endl;
    // cout<<"----------------------"<<endl;
    // for(int i=0;i<N;i++){
    // 	cout<<" "<<infov[i].cmb<< " " << infov[i].t << endl;
    // }
  }

  return 0;
}