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 (Python):
from functools import reduce

def extended_euclid(a, b):
    x1, y1, m = 1, 0, a
    x2, y2, n = 0, 1, b
    while m % n != 0:
        q, r = divmod(m, n)
        x1, y1, m, x2, y2, n = x2, y2, n, x1 - q * x2, y1 - q * y2, r
    return x2, y2, n

def modular_inverse(a, mod):
    x, _, g = extended_euclid(a, mod)
    if g != 1:
        return None 
    else:
        return x % mod

class Combinatorics:
    def __init__(self, N, mod):
        '''
        Preprocess for calculating binomial coefficients nCr (0 <= r <= n, 0 <= n <= N)
        over the finite field Z/(mod)Z.
        Input:
            N (int): maximum n
            mod (int): a prime number. The order of the field Z/(mod)Z over which nCr is calculated.
        '''
        self.mod = mod
        self.fact = [0] * (N+1)           
        self.inverse = [None] + [0] * N   
        self.fact_inverse = [0] * (N+1)   
        
        
        self.fact[0] = self.fact[1] = 1
        self.fact_inverse[0] = self.fact_inverse[1] = 1
        self.inverse[1] = 1
        for i in range(2, N+1):
            self.fact[i] = i * self.fact[i-1] % self.mod
            q, r = divmod(self.mod, i)
            self.inverse[i] = (- (q % self.mod) * self.inverse[r]) % self.mod
            self.fact_inverse[i] = self.inverse[i] * self.fact_inverse[i-1] % self.mod
    
    def perm(self, n, r):
        '''
        Calculate nPr = n! / (n-r)! % mod
        '''
        if n < r or n < 0 or r < 0: return 0
        else: return (self.fact[n] * self.fact_inverse[n-r]) % self.mod
    
    def binom(self, n, r):
        '''
        Calculate nCr = n! /(r! (n-r)!) % mod
        '''
        if n < r or n < 0 or r < 0: return 0
        else: return self.fact[n] * (self.fact_inverse[r] * self.fact_inverse[n-r] % self.mod) % self.mod
        
    def multinom(self, R):
        '''
        Calculate \binom{sum(R)}{r1, ..., r_k}
        '''
        n = sum(R)
        return self.fact[n] * reduce(lambda x, y: self.fact_inverse[x] * self.fact_inverse[y] % self.mod, R) % self.mod
        
    def hom(self, n, r):
        '''
        Calculate nHr = {n+r-1}Cr % mod.
        Assign r objects to one of n classes.
        Arrangement of r circles and n-1 partitions:
            o o o | o o | | | o | | | o o | | o
        '''
        if n == 0 and r > 0: return 0
        if n >= 0 and r == 0: return 1
        return self.binom(n + r - 1, r)

MOD = 10**9 + 7
N = int(input())
com = Combinatorics(N, MOD)
T = [[] for _ in range(N)]
for _ in range(N-1):
    a, b = map(int, input().split())
    T[a-1].append(b-1); T[b-1].append(a-1)


downward = [1] * N
upward = [1] * N
n_descs = [1] * N
children_n_descs = [[] for _ in range(N)]
ans = [-1] * N

def dfs1(r):
    stack = [(r, -1, 0)] 
    while stack:
        v, p, st = stack.pop()
        if st == 0: 
            n_children = 0
            for u in T[v]:
                if u == p: continue
                if n_children == 0:
                    stack += [(v, p, 2), (u, v, 0)]
                    n_children += 1
                else:
                    stack += [(v, p, 1), (u, v, 0)]
                    n_children += 1
            if n_children == 0: 
                stack += [(v, p, 2)]
        elif st == 1: 
            continue
        else: 
            n = n_descs[v]
            downward[v] = (downward[v] * com.fact[n-1]) % MOD
            if p != -1:
                n_descs[p] += n
                downward[p] = ((downward[p] * downward[v]) % MOD * com.fact_inverse[n]) % MOD

def dfs2(r):
    f_n1, f_n1_inv = com.fact[N-1], com.fact_inverse[N-1]
    stack = [(r, -1)] 
    while stack:
        v, p = stack.pop()
        n_v = n_descs[v]
        dw_v = downward[v]
        if p == -1: upward[v] = 1
        else: upward[v] = ans[p] * com.fact[N-1-n_v] % MOD * com.fact[n_v] % MOD * modular_inverse(dw_v, MOD) % MOD * f_n1_inv % MOD
        ans[v] = upward[v] * downward[v] % MOD * f_n1 % MOD * com.fact_inverse[N-n_v] % MOD * com.fact_inverse[n_v-1] % MOD
        for u in T[v]:
            if u == p: continue
            stack += [(u, v)]
dfs1(0)
dfs2(0)
for a in ans: print(a)

Solution (Python):
import sys

sys.setrecursionlimit(10 ** 5 * 2 + 10)

MOD = 10 ** 9 + 7
inv = [None, 1]
for i in range(2, 10 ** 5 * 2 + 1):
    inv.append(MOD - MOD // i * inv[MOD % i] % MOD)

fact = [1]
ifact = [1]
for i in range(1, 10 ** 5 * 2 + 1):
    fact.append((i * fact[-1]) % MOD)
    ifact.append((inv[i] * ifact[-1]) % MOD)


class Node:
    def __init__(self, ind):
        self.ind = ind
        self.val = 1
        self.ndesc = 1
        self.neighs = []

    def calc(self, fro):
        for neigh in self.neighs:
            if neigh.ind == fro:
                continue
            neigh.calc(self.ind)
            self.val = self.val * neigh.val * ifact[neigh.ndesc] % MOD
            self.ndesc += neigh.ndesc
        self.val = self.val * fact[self.ndesc - 1] % MOD

    def comp(self, fro, carry):
        self.val = carry * self.ndesc * inv[max(1, N - self.ndesc)] % MOD
        for neigh in self.neighs:
            if neigh.ind == fro:
                continue
            neigh.comp(self.ind, self.val)


N = int(input())
nodes = [Node(i) for i in range(N)]
for _ in range(N - 1):
    a, b = map(int, input().split())
    nodes[a - 1].neighs.append(nodes[b - 1])
    nodes[b - 1].neighs.append(nodes[a - 1])
nodes[0].calc(0)
nodes[0].comp(0, (nodes[0].val * inv[N]) % MOD)
for i in range(N):
    print(nodes[i].val)

Solution (Python):
MOD = 10 ** 9 + 7
inv = [None, 1]
for i in range(2, 10 ** 5 * 2 + 1):
    inv.append(MOD - MOD // i * inv[MOD % i] % MOD)

fact = [1]
ifact = [1]
for i in range(1, 10 ** 5 * 2 + 1):
    fact.append((i * fact[-1]) % MOD)
    ifact.append((inv[i] * ifact[-1]) % MOD)


class Node:
    def __init__(self, ind):
        self.ind = ind
        self.val = 1
        self.ndesc = 1
        self.neighs = []


N = int(input())
nodes = [Node(i) for i in range(N)]
for _ in range(N - 1):
    a, b = map(int, input().split())
    nodes[a - 1].neighs.append(nodes[b - 1])
    nodes[b - 1].neighs.append(nodes[a - 1])

stack = [(-1, nodes[0])]
for i in range(N):
    fro, node = stack[i]
    for neigh in node.neighs:
        if neigh.ind == fro:
            continue
        stack.append((node.ind, neigh))

for i in range(N - 1, -1, -1):
    fro, node = stack[i]
    node.val = node.val * fact[node.ndesc - 1] % MOD
    if fro == -1:
        continue
    nodes[fro].ndesc += node.ndesc
    nodes[fro].val = nodes[fro].val * node.val * ifact[node.ndesc] % MOD

stack = [(-1, node, nodes[0].val * inv[N] % MOD)]
for i in range(N):
    fro, node, val = stack[i]
    node.val = val * node.ndesc * inv[max(1, N - node.ndesc)] % MOD
    for neigh in node.neighs:
        if neigh.ind == fro:
            continue
        stack.append((node.ind, neigh, node.val))

for i in range(N):
    print(nodes[i].val)

Solution (Python):
n = int(input())
ab = [list(map(int, input().split())) for _ in range(n - 1)]
mod = 10 ** 9 + 7

MAX = n

fact = [1] * (MAX + 1)
for i in range(1, MAX + 1):
    fact[i] = (fact[i-1] * i) % mod

inv = [1] * (MAX + 1)
for i in range(2, MAX + 1):
    inv[i] = inv[mod % i] * (mod - mod // i) % mod

fact_inv = [1] * (MAX + 1)
for i in range(1, MAX + 1):
    fact_inv[i] = fact_inv[i-1] * inv[i] % mod


adj = [[] for _ in range(n + 1)]
for a, b in ab:
    adj[a].append(b)
    adj[b].append(a)

root = 1
stack = [root]
par = [0] * (n + 1)
order = []
while stack:
    u = stack.pop()
    order.append(u)
    for v in adj[u]:
        if v == par[u]:
            continue
        par[v] = u
        stack.append(v)

size_d = [0] * (n + 1)
dp_d = [1] * (n + 1)
for v in order[::-1]:
    dp_d[v] *= fact[size_d[v]]
    dp_d[v] %= mod
    
    s = size_d[v] + 1
    p = par[v]
    size_d[p] += s
    dp_d[p] *= fact_inv[s] * dp_d[v]
    dp_d[p] %= mod

size_u = [n - 2 - e for e in size_d]
dp_u = [1] * (n + 1)
for v in order[1:]:
    p = par[v]
    x = dp_d[p]
    x *= fact_inv[size_d[p]]
    x *= fact[size_d[v] + 1]
    x *= pow(dp_d[v], mod - 2, mod)
    x *= fact[size_u[v]]
    x *= fact_inv[size_u[p] + 1]
    x *= dp_u[p]
    dp_u[v] = x % mod

for eu, su, ed, sd in zip(dp_u[1:], size_u[1:], dp_d[1:], size_d[1:]):
    su += 1
    ans = eu * ed * fact[su + sd] * fact_inv[su] * fact_inv[sd] % mod
    print(ans)

Solution (Python):
class ReRooting(object):
    """ 全方位木DP (オリジナル)"""
    def processing(self, in_:list, v:int):
        """ 単項演算(加工) """
        cnt = in_[0] * factinv[in_[1]] % MOD
        size = in_[1]
        return [cnt, size]
    
    def merge(self, in1:list, in2:list):
        """ 二項演算(マージ) """
        cnt = in1[0] * in2[0] % MOD
        size = in1[1] + in2[1]
        return [cnt, size]

    def adjustment(self, in_:list, v:int):
        """ 単項演算(調整) """
        cnt = in_[0] * fact[in_[1]] % MOD
        size = in_[1] + 1
        return [cnt, size]
    
    def solve(self):
        """ 結果を返す """
        return [cnt for cnt,_ in self.calc()]

    def __init__(self, V:int, e:list):
        """
        V: 頂点数
        e: 単位元
        """
        self.V, self.e = V, e
        self.edge = [[] for _ in range(V)]
        self.par = [-1] * V
        self.order = []
    
    def add_edge(self, u:int, v:int):
        """ 辺(u,v)をグラフに追加する """
        self.edge[u].append(v)
        self.edge[v].append(u)
    
    def topological_sort(self, root:int = 0):
        """ トポロジカルソート """
        from collections import deque
        que = deque([root])
        while que:
            v = que.popleft()
            self.order.append(v)
            for w in self.edge[v]:
                if w != self.par[v]:
                    self.par[w] = v
                    self.edge[w].remove(v)
                    que.append(w)
    
    def bottom_up(self, e:list):
        """ Bottom-Up DP """
        accBU = [e for _ in range(self.V)]
        resBU = [None] * self.V
        for v in reversed(self.order):
            for c in self.edge[v]:
                accBU[v] = self.merge(accBU[v], self.processing(resBU[c], c))
            resBU[v] = self.adjustment(accBU[v], v)
        return accBU, resBU
    
    def top_down(self, resBU:list, e:list):
        """ Top-Down DP """
        accTD = [e for _ in range(self.V)]
        resTD = [e for _ in range(self.V)]

        for p in self.order:
            ac = self.processing(resTD[p], p)
            for v in self.edge[p]:
                accTD[v] = ac[:]
                ac = self.merge(ac, self.processing(resBU[v], v))
            
            ac = e
            for v in reversed(self.edge[p]):
                accTD[v] = self.merge(accTD[v], ac)
                resTD[v] = self.adjustment(accTD[v], v)
                ac = self.merge(ac, self.processing(resBU[v], v))
        return resTD
    
    def calc(self):
        """ 開始条件: 木を構築済み """
        self.topological_sort()
        accBU, resBU = self.bottom_up(self.e)
        resTD = self.top_down(resBU, self.e)

        res = [None] * self.V
        for v in range(self.V):
            res[v] = self.processing(resTD[v], v)
            res[v] = self.merge(accBU[v], res[v])
            res[v] = self.adjustment(res[v], v)
        return res


import sys
input = sys.stdin.readline

N = int(input())
MOD = 10 ** 9 + 7

fact = [1] * (N + 1) 
factinv = [1] * (N + 1) 
for i in range(N):
    fact[i + 1] = fact[i] * (i + 1) % MOD
factinv[-1] = pow(fact[-1], MOD - 2, MOD)
for i in range(N - 1, -1, -1):
    factinv[i] = factinv[i + 1] * (i + 1) % MOD
 
def main():
    RR = ReRooting(N, [1, 0])
    for _ in range(N - 1):
        a, b = map(int, input().split())
        RR.add_edge(a - 1, b- 1)
    print(*RR.solve(), sep="\n")

 
if __name__ == "__main__":
    main()

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 7)
class Tree:
  C, RL = {}, {}
  R, N, D, S, P, T = None, None, None, None, None, None
  TL = None
  def __init__(s, num):
    s.N = num
  def set(s, a, b):
    if a in s.C: s.C[a].append(b)
    else: s.C[a] = [b]
    if b in s.C: s.C[b].append(a)
    else: s.C[b] = [a]
  def makeRank(s, root):
    s.R = [0] * s.N 
    s.R[root] = 1
    s.RL[1] = [root] 
    s.S = {} 
    s.P = [-1] * s.N 
    s.D = 1
    while s.RL[s.D] != []:
      s.D += 1
      s.RL[s.D] = []
      for i in s.RL[s.D - 1]:
        for j in s.C[i]:
          if s.R[j] == 0:
            s.R[j] = s.D
            s.RL[s.D].append(j)
            if i not in s.S: s.S[i] = [j]
            else: s.S[i].append(j)
            s.P[j] = i      
  def bottomUpDP(s):
    for i in range(s.D - 2, 0, -1):
      T = s.RL[i]
      for j in T:
        if j not in s.S: continue
        for k in s.S[j]:
          s.dp_sub_exe(j, k)
  def topDownDP(s):
    for i in range(2, s.D):
      T = s.RL[i]
      for j in T:
        s.dp_sub_exe_inv(j, s.P[j])
  def allDP(s):
    s.dp_init()
    s.bottomUpDP()
    s.topDownDP()
    return s.DP
  def dp_init(s): 
    s.DP = [1] * N
    s.sDP = [1] * N
  def dp_sub_exe(s, x, y): 
    s.sDP[x] += s.sDP[y]
    s.DP[x] = s.DP[x] * s.DP[y] * com.com(s.sDP[x] - 1, s.sDP[y]) % MOD
  def dp_sub_exe_inv(s, x, y): 
    t = com.com(s.sDP[y] - 1, s.sDP[x]) * s.DP[x] % MOD
    t = s.DP[y] * s.inv(t, MOD)
    k = s.sDP[y] - s.sDP[x]
    k = com.com(s.sDP[y] - 1, k) % MOD
    s.sDP[x] = s.sDP[y]
    s.DP[x] = s.DP[x] * t * k % MOD
  def inv(s, a, mod): 
    return pow(a, mod - 2, mod)
  
class comb():
  F = [1, 1]
  Fi = [1, 1]
  I = [0, 1]
  def __init__(self, num, mod):
    self.MOD = mod
    for i in range(2, num + 1):
      self.F.append((self.F[-1] * i) % mod)
      self.I.append(mod - self.I[mod % i] * (mod // i) % mod)
      self.Fi.append(self.Fi[-1] * self.I[i] % mod)
  def com(self, n, k):
    if n < k: return 0
    if n < 0 or k < 0: return 0
    return self.F[n] * (self.Fi[k] * self.Fi[n - k] % self.MOD) % self.MOD

N = int(input())
ab = [list(map(int, input().split())) for _ in range(N - 1)]

MOD = 10 ** 9 + 7
com = comb(N, MOD)

T = Tree(N)
for a, b in ab:
  a -= 1
  b -= 1
  T.set(a, b)

T.makeRank(0)
DP = T.allDP()

for i in DP:
  print(i)

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 7)
class Tree:
  C, RL = {}, {}
  R, N, D, S, P, T = None, None, None, None, None, None
  TL = None
  def __init__(s, num):
    s.N = num
  def set(s, a, b):
    if a in s.C: s.C[a].append(b)
    else: s.C[a] = [b]
    if b in s.C: s.C[b].append(a)
    else: s.C[b] = [a]
  def makeRank(s, root):
    s.R = [0] * s.N 
    s.R[root] = 1
    s.RL[1] = [root] 
    s.S = {} 
    s.P = [-1] * s.N 
    F = [root]
    s.D = 2
    while F != []:
      Ft = []
      s.RL[s.D] = []
      for i in F:
        for j in s.C[i]:
          if s.R[j] == 0:
            s.R[j] = s.D
            Ft.append(j)
            s.RL[s.D].append(j)
            if i not in s.S:
              s.S[i] = [j]
            else:
              s.S[i].append(j)
            s.P[j] = i
      s.D += 1
      F = Ft
  def dfs(s, x, y, r): 
    if x == y:
      return [x]
    for i in s.C[x]:
      if i != r:
        t = s.dfs(i, y, x)
        if t != False:
          return [x] + t
    return False
  def dist(s, x): 
    t = [-1] * s.N
    S = [x]
    ans = x
    ansn = 0
    t[x] = 0
    while S != []:
      k = S.pop()
      for i in s.C[k]:
        if t[i] == -1:
          t[i] = t[k] + 1
          S.append(i)
          if t[i] > ansn:
            ansn = t[i]
            ans = i
    return ans, ansn
  def getDi(s, x = 0): 
    a, _ = s.dfs(x)
    b, ans = s.dfs(a)
    return ans
  def getDeep(s, x): 
    ans = 0
    if x in s.S:
      for i in s.S[x]:
        ans = max(ans, s.getDeep(i))
      return ans + 1
    else:
      return 0
  def getParent(s, x, n): 
    if n == 0:
      return x
    if s.P[x] == -1:
      return -n
    return s.getParent(s.P[x], n - 1)
  def tour(s): 
    x = s.RL[1][0]
    s.T = [] 
    s.TL = [[] for _ in range(s.N)] 
    s.TL[x].append(len(s.T))
    s.T.append(x)
    for i in (s.S[s.RL[1][0]]):
      s.tour_sub(i)
    return s.T
  def tour_sub(s, x): 
    s.TL[x].append(len(s.T))
    s.T.append(x)
    if x in s.S:
      for i in (s.S[x]):
        s.tour_sub(i)
    s.TL[s.P[x]].append(len(s.T))
    s.T.append(s.P[x])
  def bottomUpDP(s):
    s.dp_init()
    for i in range(s.D - 1, 0, -1):
      T = s.RL[i]
      for j in T:
        s.dp_sub(j)
  def allDP(s):
    bDP = s.bottomUpDP()
    for i in range(2, s.D):
      T = s.RL[i]
      for j in T:
        s.dp_sub_exe_inv(j, s.P[j])
  def dp_init(s): 
    s.DP = [1] * N
    s.sDP = [1] * N
  def dp_sub(s, x):
    if x not in s.S:
      return 0
    T = s.S[x]
    for i in T:
      s.dp_sub_exe(x, i)
  def dp_sub_exe(s, x, y): 
    s.sDP[x] += s.sDP[y]
    s.DP[x] = s.DP[x] * s.DP[y] * com.com(s.sDP[x] - 1, s.sDP[y]) % MOD
  def dp_sub_exe_inv(s, x, y): 
    t = com.com(s.sDP[y] - 1, s.sDP[x]) * s.DP[x] % MOD
    t = s.DP[y] * s.inv(t, MOD)
    k = s.sDP[y] - s.sDP[x]
    k = com.com(s.sDP[y] - 1, k) % MOD
    s.sDP[x] = s.sDP[y]
    s.DP[x] = s.DP[x] * t * k % MOD
    return 
  def inv(s, a, mod): 
    return pow(a, mod - 2, mod)
  
class comb():
  F = [1, 1]
  Fi = [1, 1]
  I = [0, 1]
  def __init__(self, num, mod):
    self.MOD = mod
    for i in range(2, num + 1):
      self.F.append((self.F[-1] * i) % mod)
      self.I.append(mod - self.I[mod % i] * (mod // i) % mod)
      self.Fi.append(self.Fi[-1] * self.I[i] % mod)
  def com(self, n, k):
    if n < k: return 0
    if n < 0 or k < 0: return 0
    return self.F[n] * (self.Fi[k] * self.Fi[n - k] % self.MOD) % self.MOD

N = int(input())
ab = [list(map(int, input().split())) for _ in range(N - 1)]

MOD = 10 ** 9 + 7
com = comb(N, MOD)

T = Tree(N)
for a, b in ab:
  a -= 1
  b -= 1
  T.set(a, b)

T.makeRank(0)
T.allDP()

for i in T.DP:
  print(i)

Solution (Python):
class ReRooting(object):
    """ 全方位木DP """
    def merge(self, a, b):
        """ 二項演算 a・b """
        return a * b % MOD
 
    def adj_bu(self, accBU, v:int):
        """
        Bottom-Upの単項演算 g(accBU[v])
 
        v: 頂点
        """
        return accBU * inv(self.SIZE[v]) % MOD
 
    def adj_td(self, accTD, v:int, p:int):
        """
        Top-Downの単項演算 g(accTD[v])
 
        v: 頂点
        p: 親
        """
        return accTD * inv(self.V - self.SIZE[v]) % MOD
 
    def adj_fin(self, acc, v:int):
        """
        最終結果の単項演算 g(acc[v])
 
        v: 頂点
        """
        return acc * fact[self.V - 1] % MOD

    def __init__(self, V:int, e:int):
        """
        V: 頂点数
        e: 単位元
        """
        self.V, self.e = V, e
        self.edge = [[] for _ in range(V)]
        self.par = [-1] * V
        self.order = []
        self.SIZE = [1] * self.V
    
    def subtree_size(self):
        """ 部分木のサイズを求める """
        for v in reversed(self.order[1:]):
            self.SIZE[self.par[v]] += self.SIZE[v]

    def add_edge(self, u:int, v:int):
        """ 辺(u,v)をグラフに追加する """
        self.edge[u].append(v)
        self.edge[v].append(u)
    
    def topological_sort(self, root:int = 0):
        """ トポロジカルソート """
        from collections import deque
        que = deque([root])
        while que:
            v = que.popleft()
            self.order.append(v)
            for w in self.edge[v]:
                if w != self.par[v]:
                    self.par[w] = v
                    que.append(w)
    
    def bottom_up(self):
        """ Bottom-Up DP """
        root = self.order[0]
        accBU = [self.e] * self.V
        resBU = [self.e] * self.V

        for v in reversed(self.order):
            resBU[v] = self.adj_bu(accBU[v], v)

            if v == root: break

            p = self.par[v]
            accBU[p] = self.merge(accBU[p], resBU[v])

        return accBU, resBU
    
    def top_down(self, resBU:list):
        """ Top-Down DP """
        accTD = [self.e] * self.V
        resTD = [self.e] * self.V

        for p in self.order:
            ac = resTD[p]
            for v in self.edge[p]:
                if v == self.par[p]: continue
                accTD[v] = ac
                ac = self.merge(ac, resBU[v])

            ac = self.e
            for v in reversed(self.edge[p]):
                if v == self.par[p]: continue
                accTD[v] = self.merge(accTD[v], ac)
                ac = self.merge(ac, resBU[v])
                resTD[v] = self.adj_td(accTD[v], v, p)

        return resTD
    
    def solve(self):
        self.topological_sort()
        self.subtree_size()
        accBU, resBU = self.bottom_up()
        resTD = self.top_down(resBU)
        res = [self.adj_fin(self.merge(a, b), v) for v,(a,b) in enumerate(zip(accBU, resTD))]
        return res


N = int(input())
MOD = 10 ** 9 + 7
 
fact = [1] * (N + 1) 
factinv = [1] * (N + 1) 
for i in range(N):
    fact[i + 1] = fact[i] * (i + 1) % MOD
factinv[-1] = pow(fact[-1], MOD - 2, MOD)
for i in range(N - 1, -1, -1):
    factinv[i] = factinv[i + 1] * (i + 1) % MOD
inv = lambda n: fact[n - 1] * factinv[n] % MOD 
 
def main():
    RR = ReRooting(N, 1)
    for _ in range(N - 1):
        a, b = map(int, input().split())
        RR.add_edge(a - 1, b- 1)
 
    print(*RR.solve(), sep="\n")
 
if __name__ == "__main__":
    main()

Solution (Python):
class ReRooting(object):
    """ 全方位木DP """
    def merge(self, a, b):
        """ 二項演算 a・b """
        return a * b % MOD

    def adj_bu(self, accBU, v:int):
        """
        Bottom-Upの単項演算 g(accBU[v])

        v: 頂点
        """
        return accBU * inv(self.SIZE[v]) % MOD

    def adj_td(self, accTD, v:int, p:int):
        """
        Top-Downの単項演算 g(accTD[v])

        v: 頂点
        p: 親
        """
        return accTD * inv(self.V - self.SIZE[v]) % MOD

    def adj_fin(self, acc, v:int):
        """
        最終結果の単項演算 g(acc[v])

        v: 頂点
        """
        return acc * fact[self.V - 1] % MOD

    def __init__(self, V:int, e:int):
        """
        V: 頂点数
        e: 単位元
        """
        self.V, self.e = V, e
        self.edge = [[] for _ in range(V)]
        self.par = [-1] * V
        self.order = []
        self.SIZE = [1] * self.V
    
    def subtree_size(self):
        """ 部分木のサイズを求める """
        for v in reversed(self.order[1:]):
            self.SIZE[self.par[v]] += self.SIZE[v]

    def add_edge(self, u:int, v:int):
        """ 辺(u,v)をグラフに追加する """
        self.edge[u].append(v)
        self.edge[v].append(u)
    
    def topological_sort(self, root:int = 0):
        """ トポロジカルソート """
        from collections import deque
        que = deque([root])
        while que:
            v = que.popleft()
            self.order.append(v)
            for w in self.edge[v]:
                if w != self.par[v]:
                    self.par[w] = v
                    self.edge[w].remove(v)
                    que.append(w)
    
    def bottom_up(self):
        """ Bottom-Up DP """
        root = self.order[0]
        accBU = [self.e] * self.V
        resBU = [self.e] * self.V

        for v in reversed(self.order):
            resBU[v] = self.adj_bu(accBU[v], v)

            if v == root: break

            p = self.par[v]
            accBU[p] = self.merge(accBU[p], resBU[v])
        return accBU, resBU
    
    def top_down(self, resBU:list):
        """ Top-Down DP """
        accTD = [self.e] * self.V
        resTD = [self.e] * self.V

        for p in self.order:
            
            ac = resTD[p]
            for v in self.edge[p]:
                accTD[v] = ac
                ac = self.merge(ac, resBU[v])

            
            ac = self.e
            for v in reversed(self.edge[p]):
                accTD[v] = self.merge(accTD[v], ac)
                ac = self.merge(ac, resBU[v])
                
                resTD[v] = self.adj_td(accTD[v], v, p)
        return resTD
    
    def solve(self):
        self.topological_sort()
        self.subtree_size()
        accBU, resBU = self.bottom_up()
        resTD = self.top_down(resBU)
        res = [self.adj_fin(self.merge(a, b), v) for v,(a,b) in enumerate(zip(accBU, resTD))]
        return res


N = int(input())
MOD = 10 ** 9 + 7

fact = [1] * (N + 1) 
factinv = [1] * (N + 1) 
for i in range(N):
    fact[i + 1] = fact[i] * (i + 1) % MOD
factinv[-1] = pow(fact[-1], MOD - 2, MOD)
for i in range(N - 1, -1, -1):
    factinv[i] = factinv[i + 1] * (i + 1) % MOD
inv = lambda n: fact[n - 1] * factinv[n] % MOD 

def main():
    RR = ReRooting(N, 1)
    for _ in range(N - 1):
        a, b = map(int, input().split())
        RR.add_edge(a - 1, b- 1)

    print(*RR.solve(), sep="\n")

if __name__ == "__main__":
    main()

Solution (Python):
import sys
input = sys.stdin.buffer.readline
 
class Combination:
    def __init__(self, size, mod=10**9 + 7):
        self.size = size + 2
        self.mod = mod
        self.fact = [1, 1] + [0] * size
        self.factInv = [1, 1] + [0] * size
        self.inv = [0, 1] + [0] * size
 
        for i in range(2, self.size):
            self.fact[i] = self.fact[i - 1] * i % self.mod
            self.inv[i] = -self.inv[self.mod % i] * (self.mod // i) % self.mod
            self.factInv[i] = self.factInv[i - 1] * self.inv[i] % self.mod
 
    def npr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * self.factInv[n - r] % self.mod
 
    def ncr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * (self.factInv[r] * self.factInv[n - r] % self.mod) % self.mod
 
    def nhr(self, n, r):  
        return self.ncr(n + r - 1, n - 1)
 
    def factN(self, n):
        if n < 0:
            return 0
        return self.fact[n]
 
    def factInvN(self, n):
        if n < 0:
            return 0
        return self.factInv[n]
 
N = int(input())
MOD = 10**9 + 7
comb = Combination(N + 100)
 
edges = [[] for _ in range(N + 1)]
for _ in range(N - 1):
    fr, to = map(int, input().split())
    edges[fr].append(to)
    edges[to].append(fr)
 
order = []
parent = [0] * (N + 1)
st = [1]
while st:
    now = st.pop()
    order.append(now)
    for to in edges[now]:
        if to == parent[now]:
            continue
        st.append(to)
        parent[to] = now
 
size = [1] * (N + 1)
for v in order[::-1]:
    size[parent[v]] += size[v]
 
dpLeaf = [1] * (N + 1)
for v in order[:: -1]:
    pr = parent[v]
    dpLeaf[v] = dpLeaf[v] * comb.fact[size[v] - 1] % MOD
    dpLeaf[pr] = dpLeaf[pr] * dpLeaf[v] * comb.factInv[size[v]] % MOD
 
ans = [0] * (N + 1)
ans[1] = dpLeaf[1]
for v in order[1:]:
    pr = parent[v]
    ans[v] = ans[pr] * comb.inv[N - size[v]] * size[v] % MOD
 
print(*(ans[1:]), sep='\n')

Solution (Python):
import sys
sys.setrecursionlimit(1000000)


def input():
    return sys.stdin.readline()


n = int(input())
e = [[] for _ in range(n)]
for _ in range(n-1):
    a, b = [int(i) - 1 for i in input().split()]
    e[a].append(b)
    e[b].append(a)

mod = 10**9+7

kkai = [1]
for i in range(1, 2*10 ** 5):
    kkai.append(kkai[-1] * i % mod)


def kai(x, p=mod):
    return kkai[x]


def comb(a, b, p=mod):
    if a < 0 or b < 0:
        return 0
    elif a < b:
        return 0
    if b == 0:
        return 1
    c = 1
    c *= kai(a, p)
    c *= pow(kai(b, p), p - 2, p)
    c *= pow(kai(a - b, p), p - 2, p)
    return c % p


child = [0] * n


def dfs1(i=0, r=-1):
    s = 1
    for j in e[i]:
        if j == r:
            continue
        s += dfs1(j, i)
    child[i] = s
    return s


dfs1()
a = [0] * n


def dfs2(i=0, r=-1):
    s = kai(child[i]-1)
    t = 1
    for j in e[i]:
        if j == r:
            continue
        s *= dfs2(j, i)
        s %= mod
        t *= kai(child[j])
        t %= mod
    s *= pow(t, mod - 2, mod)
    s %= mod
    a[i] = s
    return s


dfs2()
b = [0] * n


def dfs3(i=0, r=-1):
    if r == -1:
        b[i] = a[i]
    else:
        s = b[r] * child[i] % mod
        s *= pow(n-child[i], mod - 2, mod)
        s %= mod
        b[i] = s

    for j in e[i]:
        if j == r:
            continue
        dfs3(j, i)


dfs3()
print("\n".join(map(str, b)))

Solution (Python):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from bisect import bisect_right, bisect_left
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor, gamma, log
from operator import mul
from functools import reduce
from copy import deepcopy

sys.setrecursionlimit(2147483647)
INF = 10 ** 20
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 10 ** 9 + 7

n =I()
G = [[] for _ in range(n)]
for _ in range(n - 1):
    a, b = LI()
    G[a - 1] += [b - 1]
    G[b - 1] += [a - 1]

fac = [1] * (n + 1)
inv = [1] * (n + 1)
for j in range(1, n + 1):
    fac[j] = fac[j-1] * j % mod

inv[n] = pow(fac[n], mod-2, mod)
for j in range(n-1, -1, -1):
    inv[j] = inv[j+1] * (j+1) % mod

def comb(n, r):
    if r > n or n < 0 or r < 0:
        return 0
    return fac[n] * inv[n - r] * inv[r] % mod

v_num = [-1] * n
par = [-1] * n
def f(u):
    ret = 1
    for v in G[u]:
        if v == par[u]:
            continue
        par[v] = u
        ret += f(v)
    v_num[u] = ret
    if u: return ret

f(0)
dp = [0] * n

def tree_dp(x):
    c = 1
    remain_v = v_num[x] - 1
    for y in G[x]:
        if y == par[x]:
            continue
        c = c * tree_dp(y) * comb(remain_v, v_num[y]) % mod
        remain_v -= v_num[y]
    dp[x] = c
    if x: return c

tree_dp(0)
ans = [0] * n

def dfs(d):
    e = 1
    inv_e = pow(comb(n - 1, v_num[d]) * dp[d], mod - 2, mod)
    ans[d] = dp[d] * ans[par[d]] * comb(n - 1, v_num[d] - 1) * inv_e % mod

q = deque([0])
ans[0] = dp[0]
while q:
    g = q.pop()
    for h in G[g]:
        if h == par[g]:
            continue
        dfs(h)
        q += [h]

for j in ans:
    print(j)