Problem:
Score : 600 points

Problem Statement

We have a tree with N vertices numbered 1 to N. The i-th edge in this tree connects Vertex a_i and b_i.
For each k=1, ..., N, solve the problem below:

Consider writing a number on each vertex in the tree in the following manner:

First, write 1 on Vertex k.

Then, for each of the numbers 2, ..., N in this order, write the number on the vertex chosen as follows:

Choose a vertex that still does not have a number written on it and is adjacent to a vertex with a number already written on it. If there are multiple such vertices, choose one of them at random.

Find the number of ways in which we can write the numbers on the vertices, modulo (10^9+7).

Constraints

2 \leq N \leq 2 \times 10^5

1 \leq a_i,b_i \leq N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
:
a_{N-1} b_{N-1}

Output

For each k=1, 2, ..., N in this order, print a line containing the answer to the problem.

Sample Input 1

3
1 2
1 3

Sample Output 1

2
1
1

The graph in this input is as follows:

For k=1, there are two ways in which we can write the numbers on the vertices, as follows:

Writing 1, 2, 3 on Vertex 1, 2, 3, respectively

Writing 1, 3, 2 on Vertex 1, 2, 3, respectively

Sample Input 2

2
1 2

Sample Output 2

1
1

The graph in this input is as follows:

Sample Input 3

5
1 2
2 3
3 4
3 5

Sample Output 3

2
8
12
3
3

The graph in this input is as follows:

Sample Input 4

8
1 2
2 3
3 4
3 5
3 6
6 7
6 8

Sample Output 4

40
280
840
120
120
504
72
72

The graph in this input is as follows:

Solution in C++ (Clang 10.0.0) (judge verdict: Wrong Answer)

#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <tuple>
#include <string>
#include <algorithm>
#include <functional> // greater など
#include <cmath> // abs など
#include <numeric> // accumulate など
#include <stdexcept>
#include <cassert>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long ll;

// #define DEBUG 1
// debug
// https://trap.jp/post/998/
void debug_out() { cout << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T)
{
  clog << H << " ";
  debug_out(T...);
}
#ifdef DEBUG
#define debug(...) debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

const ll bigprime = 1000000007;
const int MAX_N = 200009;
int size_ambient_tree;
vector<ll> modfactmemo(MAX_N);
/*
struct edge
{
  int from, to;
};
vector<edge> edges;
*/
vector<ll> dp1(MAX_N); // 1回目の探索での結果
vector<ll> dp2(MAX_N); // 最終的な結果
const ll identity = 1; // モノイドの単位元
const int initial_root = 0; // 1回目の根
vector<vector<ll>> accum_l(MAX_N); // 2回目の探索での累積(左から)
vector<vector<ll>> accum_r(MAX_N); // 2回目の探索での累積(右から)
vector<int> sizes_subtree(MAX_N); // initial_root を根としたときの、各ノードを根とする部分木のサイズ
vector<vector<int>> adjs(MAX_N); // 隣接するノードのリスト
vector<int> index_adjs(MAX_N); // 親の何番目のadjsか？

ll modfact(int n)
{
  modfactmemo.at(0) = 1;
  if (n < 0)
  {
    throw domain_error("modfact: n must not be negative");
  }
  /*
  else if (n == 0)
  {
    return 1;
  }
  else
  {
    return modfact(n - 1) * n % bigprime;
  }
   */
  else if (n >= modfactmemo.size())
  {
    ll res = modfact(n - 1);
    modfactmemo.at(n) = res * n % bigprime;
  }
  return modfactmemo.at(n);
}

ll modpow(ll n, ll k)
{
  if (k < 0)
  {
    throw domain_error("modpow: k must not be negative");
  }
  else if (k == 0)
  {
    return 1;
  }
  else if (k % 2 == 0)
  {
    ll res = modpow(n, k / 2);
    return res * res % bigprime;
  }
  else
  {
    ll res = modpow(n, k - 1);
    return res * n % bigprime;
  }
}

inline ll modinv(ll n)
{
  ll m = n % bigprime;
  if (m == 0)
  {
    throw domain_error("modinv: 0 is not invertible");
  }
  return modpow(m, bigprime - 2);
}

// dp2の値から結果を求める
inline ll convert_result(int size_subtree, ll arg)
{
  return modfact(size_subtree) * arg % bigprime;
}

// 子すべてでの値をマージした値から、あるnodeでの値を得る
// size_subtreeはnodeを含めて数える
inline ll calc_on_node(int size_subtree, ll merged)
{
  return modinv(size_subtree) * merged % bigprime;
}

// モノイド演算
inline ll merge(ll x, ll y)
{
  return x * y % bigprime;
}

// 普通の木DPでsize_subtree, dp1, index_adjsを求める
void dfs1(const int node, const int parent)
{
  int size_subtree = 1; // node以下の部分木のサイズ
  ll merged = identity; // nodeの子すべてでの値をマージした値

  // 子を順番に処理
  for (int i = 0; i < adjs.at(node).size(); i++)
  {
    // 親は無視
    const int child = adjs.at(node).at(i);
    if (child == parent)
    {
      continue;
    }

    dfs1(child, node);

    // 値を更新
    index_adjs.at(child) = i;
    size_subtree += sizes_subtree.at(child);
    merged = merge(merged, dp1.at(child));
  }

  // 値を格納
  sizes_subtree.at(node) = size_subtree;
  dp1.at(node) = calc_on_node(size_subtree, merged);
}

// 全方位木DPでdp2を求める
void dfs2(int node, int parent)
{
  ll parent_res; // 全体の木からnode以下の部分木を取り除きparentを根として得られる部分木での値

  // 親がいればparent_resを求める
  // 親がいないなら定義されない
  if (node != initial_root)
  {
    int index = index_adjs.at(node);
    // node以外のparentの子すべてでの値をマージした値
    ll parent_merged = merge(accum_l.at(parent).at(index), accum_r.at(parent).at(index));
    parent_res = calc_on_node(size_ambient_tree - sizes_subtree.at(node), parent_merged);
  }

  // accum_l, accum_r, dp2 を求める
  const int num_adjs = adjs.at(node).size();
  accum_l.at(node).resize(num_adjs + 1); // すべてマージした値も求めておくため+1してある
  accum_l.at(node).at(0) = identity;
  accum_r.at(node).resize(num_adjs);
  accum_r.at(node).at(num_adjs - 1) = identity;
  for (int i = 1; i <= num_adjs; i++)
  {
    int adj = adjs.at(node).at(i - 1);
    ll res = (adj == parent) ? parent_res : dp1.at(adj);
    accum_l.at(node).at(i) = merge(accum_l.at(node).at(i - 1), res);
  }
  for (int i = num_adjs - 2; i >= 0; i--)
  {
    int adj = adjs.at(node).at(i + 1);
    ll res = (adj == parent) ? parent_res : dp1.at(adj);
    accum_r.at(node).at(i) = merge(accum_r.at(node).at(i + 1), res);
  }
  dp2.at(node) = calc_on_node(size_ambient_tree, accum_l.at(node).at(num_adjs));

  // 子についても処理する
  for (const int child : adjs.at(node))
  {
    if (child == parent)
    {
      continue;
    }
    dfs2(child, node);
  }
}

int main()
{
  // 入力を取る
  cin >> size_ambient_tree;
  rep(i, size_ambient_tree - 1)
  {
    int a, b;
    cin >> a >> b;
    a--; b--; // 入力では1から始まるのでデクリメントする必要がある!
    // edges.push_back(edge{a, b});
    adjs.at(a).push_back(b);
    adjs.at(b).push_back(a);
  }

  // 処理
  // index_adjs.at(initial_root) = -1;
  dfs1(initial_root, -1);
  dfs2(initial_root, -1);

  // 出力
  rep(i, size_ambient_tree)
  {
    cout << convert_result(size_ambient_tree, dp2.at(i)) << endl;
  }
}