Problem p02728 (python)

Fixed submission:
# -*- coding: utf-8 -*-
"""
Created on Fri May  8 12:10:59 2020

@author: ybt07
"""

import sys
sys.setrecursionlimit(3*10**5)  # 繰り返し制限

# 組み合わせ
N = 2*10**5   # 問題サイズに合わせて変えておく
MOD = 10**9 + 7

# modint
# https://qiita.com/wotsushi/items/c936838df992b706084c

class ModInt:
    def __init__(self, x):
        self.x = x % MOD

    def __str__(self):
        return str(self.x)

    __repr__ = __str__

    def __add__(self, other):
        return (
            ModInt(self.x + other.x) if isinstance(other, ModInt) else
            ModInt(self.x + other)
        )

    def __sub__(self, other):
        return (
            ModInt(self.x - other.x) if isinstance(other, ModInt) else
            ModInt(self.x - other)
        )

    def __mul__(self, other):
        return (
            ModInt(self.x * other.x) if isinstance(other, ModInt) else
            ModInt(self.x * other)
        )

    # / : 商。　逆元はフェルマーの小定理を利用している
    '''
    def __truediv__(self, other):
        return (
            ModInt(
                self.x * pow(other.x, MOD - 2, MOD)
            ) if isinstance(other, ModInt) else
            ModInt(self.x * pow(other, MOD - 2, MOD))
        )
    '''

    def __truediv__(self, other):
        return (
            ModInt(
                self.x * inv[other.x]
            ) if isinstance(other, ModInt) else
            ModInt(self.x * inv[other])
        )


    # ** : 指数
    def __pow__(self, other):
        return (
            ModInt(pow(self.x, other.x, MOD)) if isinstance(other, ModInt) else
            ModInt(pow(self.x, other, MOD))
        )

    # x が Modint、y が通常の int の場合に、y.__add__(x) に対して、何を適用するか、定義している（→ x.__add__(y)を呼べ） 
    __radd__ = __add__

    def __rsub__(self, other):
        return (
            ModInt(other.x - self.x) if isinstance(other, ModInt) else
            ModInt(other - self.x)
        )

    __rmul__ = __mul__

    def __rtruediv__(self, other):
        return (
            ModInt(
                other.x * pow(self.x, MOD - 2, MOD)
            ) if isinstance(other, ModInt) else
            ModInt(other * pow(self.x, MOD - 2, MOD))
        )

    def __rpow__(self, other):
        return (
            ModInt(pow(other.x, self.x, MOD)) if isinstance(other, ModInt) else
            ModInt(pow(other, self.x, MOD))
        )

def cmb(n, r):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return ModInt(fac[n] * facinv[r] * facinv[n-r])

fac = [1, 1] # 元テーブル
facinv = [1, 1] #逆元テーブル
inv = [0, 1] #逆元テーブル計算用テーブル

for i in range(2, N):
    fac.append( ( fac[-1] * i ) % MOD )
    inv.append( ( -inv[MOD % i] * (MOD//i) ) % MOD )
    facinv.append( (facinv[-1] * inv[-1]) % MOD )

# 部分木のDP値を求めていく
# u : 求める頂点
# 親（親側に辿らないように） p

def dfs(u, p = -1):

    global DP, CN, E
    
    tmp_ans = 1
    tmp_cn = 0  # （自分を含む）部分木のノード数

    # u から出ている頂点 v
    for v in E[u]:
        if v != p:  # 親への辺以外について
            DP[v], CN[v] = dfs(v, u)
            tmp_cn += CN[v]
            tmp_ans *= DP[v] * cmb(tmp_cn, CN[v])
    DP[u] = tmp_ans
    CN[u] = tmp_cn + 1
            
    return tmp_ans, tmp_cn + 1

# 各頂点の真のDP値を求めていく

def bfs(u, p=-1):
    
    global DP, E
    
    tmp_ans = DP[u]
    tmp_cn = 1
    
    for v in E[u]:  # 各vに対して「真のDP値」を求めていく
        if v == p:
            continue
            
        # DP[u] と DP[v] から DP[v <- u] を求める
        tmp_cn = N - CN[v]  # v から見たときの u の部分木の要素数
        # print(v+1,tmp_cn)
        # tmp_ans = DP[u] / DP[v] / cmb(N - 1, CN[v])
                
        # DP[u <- v] を使って、DP[v] を更新する
        # DP[v] = DP[v] * tmp_ans * cmb(N-1, tmp_cn)

        # print(v+1,tmp_cn)
        # tmp_ans = DP[u] / cmb(N - 1, CN[v])
                
        # DP[u <- v] を使って、DP[v] を更新する
        DP[v] = DP[u] * CN[v] / (N - CN[v]) 

        bfs(v, u)
    
    return

# 入力処理
N = int(input())  # 頂点数
E = [[] for _ in range(N)]  # 辺の情報

for _ in range(N - 1):
    a, b = map(int, input().split())
    E[a-1].append(b-1)  # 双方向の情報
    E[b-1].append(a-1)
    
DP = [ModInt(1)] * N
CN = [0] * N

dfs(0)
bfs(0)

for i in DP:
    print(i)

Buggy submission (verdict: Runtime Error):
# -*- coding: utf-8 -*-
"""
Created on Fri May  8 16:53:25 2020

@author: ybt07
"""

# -*- coding: utf-8 -*-
"""
Created on Fri May  8 12:10:59 2020
 
@author: ybt07
"""
 
import sys
sys.setrecursionlimit(3*10**5)  # 繰り返し制限
 
# 組み合わせ
N = 2*10**5   # 問題サイズに合わせて変えておく
MOD = 10**9 + 7
 
# 入力高速化
input = lambda : sys.stdin.readline().rstrip()
 
# modint
# https://qiita.com/wotsushi/items/c936838df992b706084c
 
class ModInt:
    def __init__(self, x):
        self.x = x % MOD
 
    def __str__(self):
        return str(self.x)
 
    __repr__ = __str__
 
    def __add__(self, other):
        return (
            ModInt(self.x + other.x) if isinstance(other, ModInt) else
            ModInt(self.x + other)
        )
 
    def __sub__(self, other):
        return (
            ModInt(self.x - other.x) if isinstance(other, ModInt) else
            ModInt(self.x - other)
        )
 
    def __mul__(self, other):
        return (
            ModInt(self.x * other.x) if isinstance(other, ModInt) else
            ModInt(self.x * other)
        )
 
    # / : 商。　逆元はフェルマーの小定理を利用している
    def __truediv__(self, other):
        return (
            ModInt(
                self.x * inv[other.x]
            ) if isinstance(other, ModInt) else
            ModInt(self.x * inv[other])
        )
 
    # ** : 指数
    def __pow__(self, other):
        return (
            ModInt(pow(self.x, other.x, MOD)) if isinstance(other, ModInt) else
            ModInt(pow(self.x, other, MOD))
        )
 
    # x が Modint、y が通常の int の場合に、y.__add__(x) に対して、何を適用するか、定義している（→ x.__add__(y)を呼べ） 
    __radd__ = __add__
 
    def __rsub__(self, other):
        return (
            ModInt(other.x - self.x) if isinstance(other, ModInt) else
            ModInt(other - self.x)
        )
 
    __rmul__ = __mul__
 
    def __rtruediv__(self, other):
        return (
            ModInt(
                other.x * inv[self.x]
            ) if isinstance(other, ModInt) else
            ModInt(other * inv[self.x])
        )
 
    def __rpow__(self, other):
        return (
            ModInt(pow(other.x, self.x, MOD)) if isinstance(other, ModInt) else
            ModInt(pow(other, self.x, MOD))
        )
 
def cmb(n, r):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return fac[n] * facinv[r] * facinv[n-r] % MOD
 
fac = [1, 1] # 元テーブル
facinv = [1, 1] # 逆元テーブル
inv = [0, 1] # 逆元テーブル計算用テーブル
 
for i in range(2, N):
    fac.append( ( fac[-1] * i ) % MOD )
    inv.append( ( -inv[MOD % i] * (MOD//i) ) % MOD )
    facinv.append( (facinv[-1] * inv[-1]) % MOD )
 
# 部分木のDP値を求めていく
# u : 求める頂点
# 親（親側に辿らないように） p
 
def dfs(u, p = -1):
 
    global DP, CN, E
    
    # tmp_ans = 1
    # tmp_cn = 0  # （自分を含む）部分木のノード数
 
    # u から出ている頂点 v
    for v in E[u]:
        if not v == p:  # 親への辺以外について
            DP[v], CN[v] = dfs(v, u)
            CN[u] += CN[v]
            DP[u] *= DP[v] * cmb(CN[u], CN[v])
    CN[u] += 1
            
    return DP[u], CN[u]
 
# 各頂点の真のDP値を求めていく
 
def bfs(u, p=-1):
    
    global DP, E
        
    for v in E[u]:  # 各vに対して「真のDP値」を求めていく
        if v == p:
            continue
            
        # DP[u] と DP[v] から DP[v <- u] を求める
        cnv = CN[v]
        tmp_cn = N - cnv  # v から見たときの u の部分木の要素数
        DP[v] = DP[u] * cnv / tmp_cn 
 
        bfs(v, u)
    
    return

def main(): 
    # 入力処理
    N = int(input())  # 頂点数
    
    E = [[]*N for _ in range(N)]  # 辺の情報
     
    for _ in range(N - 1):
        a, b = map(int, input().split())
        E[a-1].append(b-1)  # 双方向の情報
        E[b-1].append(a-1)
        
    DP = [ModInt(1)] * N
    CN = [0] * N
     
    dfs(0)
    bfs(0)
    	 
    print(*DP, sep="\n")

main()

Buggy submission (verdict: Runtime Error):
# -*- coding: utf-8 -*-
"""
Created on Fri May  8 12:10:59 2020

@author: ybt07
"""

import sys
sys.setrecursionlimit(3*10**5)  # 繰り返し制限

# 組み合わせ
N = 2*10**5  # 問題サイズに合わせて変えておく
MOD = 10**9 + 7

# modint
# https://qiita.com/wotsushi/items/c936838df992b706084c

MOD = 10**9 + 7

class ModInt:
    def __init__(self, x):
        self.x = x % MOD

    def __str__(self):
        return str(self.x)

    __repr__ = __str__

    def __add__(self, other):
        return (
            ModInt(self.x + other.x) if isinstance(other, ModInt) else
            ModInt(self.x + other)
        )

    def __sub__(self, other):
        return (
            ModInt(self.x - other.x) if isinstance(other, ModInt) else
            ModInt(self.x - other)
        )

    def __mul__(self, other):
        return (
            ModInt(self.x * other.x) if isinstance(other, ModInt) else
            ModInt(self.x * other)
        )

    # // : 商。　逆元はフェルマーの小定理を利用している
    def __floordiv__(self, other):
        return (
            ModInt(
                self.x * inv[other.x]
            ) if isinstance(other, ModInt) else
            ModInt(self.x * inv[other])
        )

    # ** : 指数
    def __pow__(self, other):
        return (
            ModInt(pow(self.x, other.x, MOD)) if isinstance(other, ModInt) else
            ModInt(pow(self.x, other, MOD))
        )

    # x が Modint、y が通常の int の場合に、y.__add__(x) に対して、何を適用するか、定義している（→ x.__add__(y)を呼べ） 
    __radd__ = __add__

    def __rsub__(self, other):
        return (
            ModInt(other.x - self.x) if isinstance(other, ModInt) else
            ModInt(other - self.x)
        )

    __rmul__ = __mul__

    def __rtruediv__(self, other):
        return (
            ModInt(
                other.x * pow(self.x, MOD - 2, MOD)
            ) if isinstance(other, ModInt) else
            ModInt(other * pow(self.x, MOD - 2, MOD))
        )

    def __rpow__(self, other):
        return (
            ModInt(pow(other.x, self.x, MOD)) if isinstance(other, ModInt) else
            ModInt(pow(other, self.x, MOD))
        )

def cmb(n, r):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return ModInt(fac[n] * facinv[r] * facinv[n-r])

fac = [1, 1] # 元テーブル
facinv = [1, 1] #逆元テーブル
inv = [0, 1] #逆元テーブル計算用テーブル

for i in range( 2, N + 1 ):
    fac.append( ( fac[-1] * i ) % MOD )
    inv.append( ( -inv[MOD % i] * (MOD//i) ) % MOD )
    facinv.append( (facinv[-1] * inv[-1]) % MOD )

# 部分木のDP値を求めていく
# u : 求める頂点
# 親（親側に辿らないように） p

def dfs(u, p = -1):

    global DP, CN, E
    
    tmp_ans = 1
    tmp_cn = 0  # （自分を含む）部分木のノード数

    # u から出ている頂点 v
    for v in E[u]:
        if v != p:  # 親への辺以外について
            DP[v], CN[v] = dfs(v, u)
            tmp_cn += CN[v]
            tmp_ans *= DP[v] * cmb(tmp_cn, CN[v])
    DP[u] = tmp_ans
    CN[u] = tmp_cn + 1
            
    return DP[u], CN[u]

# 各頂点の真のDP値を求めていく

def bfs(u, p=-1):
    
    global DP, E
    
    tmp_ans = DP[u]
    tmp_cn = 1
    
    for v in E[u]:  # 各vに対して「真のDP値」を求めていく
        if v == p:
            continue
            
        # DP[u] と DP[v] から DP[v <- u] を求める
        tmp_cn = N - CN[v]  # v から見たときの u の部分木の要素数
        # print(v+1,tmp_cn)
        tmp_ans = DP[u] // DP[v] // cmb(N - 1, CN[v])
                
        # DP[u <- v] を使って、DP[v] を更新する
        DP[v] = DP[v] * tmp_ans * cmb(N-1, tmp_cn)
        bfs(v, u)
    
    return

# 入力処理
N = int(input())  # 頂点数
E = [[] for _ in range(N)]  # 辺の情報

for _ in range(N - 1):
    a, b = map(int, input().split())
    E[a-1].append(b-1)  # 双方向の情報
    E[b-1].append(a-1)
    
DP = [ModInt(1)] * N
CN = [0] * N

dfs(0)
bfs(0)

for i in DP:
    print(i)

Buggy submission (verdict: Runtime Error):
# -*- coding: utf-8 -*-
"""
Created on Fri May  8 12:10:59 2020

@author: ybt07
"""

import sys
sys.setrecursionlimit(3*10**5)  # 繰り返し制限

# 組み合わせ
N = 2*10**5  # 問題サイズに合わせて変えておく
MOD = 10**9 + 7

# modint
# https://qiita.com/wotsushi/items/c936838df992b706084c

MOD = 10**9 + 7

class ModInt:
    def __init__(self, x):
        self.x = x % MOD

    def __str__(self):
        return str(self.x)

    __repr__ = __str__

    def __add__(self, other):
        return (
            ModInt(self.x + other.x) if isinstance(other, ModInt) else
            ModInt(self.x + other)
        )

    def __sub__(self, other):
        return (
            ModInt(self.x - other.x) if isinstance(other, ModInt) else
            ModInt(self.x - other)
        )

    def __mul__(self, other):
        return (
            ModInt(self.x * other.x) if isinstance(other, ModInt) else
            ModInt(self.x * other)
        )

    # // : 商。　逆元はフェルマーの小定理を利用している
    def __truediv__(self, other):
        return ModInt(self.x * facinv[other.x])

    # ** : 指数
    def __pow__(self, other):
        return (
            ModInt(pow(self.x, other.x, MOD)) if isinstance(other, ModInt) else
            ModInt(pow(self.x, other, MOD))
        )

    # x が Modint、y が通常の int の場合に、y.__add__(x) に対して、何を適用するか、定義している（→ x.__add__(y)を呼べ） 
    __radd__ = __add__

    def __rsub__(self, other):
        return (
            ModInt(other.x - self.x) if isinstance(other, ModInt) else
            ModInt(other - self.x)
        )

    __rmul__ = __mul__

    def __rtruediv__(self, other):
        return (
            ModInt(
                other.x * pow(self.x, MOD - 2, MOD)
            ) if isinstance(other, ModInt) else
            ModInt(other * pow(self.x, MOD - 2, MOD))
        )

    def __rpow__(self, other):
        return (
            ModInt(pow(other.x, self.x, MOD)) if isinstance(other, ModInt) else
            ModInt(pow(other, self.x, MOD))
        )

def cmb(n, r):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return ModInt(fac[n] * facinv[r] * facinv[n-r])

fac = [1, 1] # 元テーブル
facinv = [1, 1] #逆元テーブル
inv = [0, 1] #逆元テーブル計算用テーブル

for i in range( 2, N + 1 ):
    fac.append( ( fac[-1] * i ) % MOD )
    inv.append( ( -inv[MOD % i] * (MOD//i) ) % MOD )
    facinv.append( (facinv[-1] * inv[-1]) % MOD )

# 部分木のDP値を求めていく
# u : 求める頂点
# 親（親側に辿らないように） p

def dfs(u, p = -1):

    global DP, CN, E
    
    tmp_ans = 1
    tmp_cn = 0  # （自分を含む）部分木のノード数

    # u から出ている頂点 v
    for v in E[u]:
        if v != p:  # 親への辺以外について
            DP[v], CN[v] = dfs(v, u)
            tmp_cn += CN[v]
            tmp_ans *= DP[v] * cmb(tmp_cn, CN[v]) % MOD
    
    DP[u] = tmp_ans
    CN[u] = tmp_cn + 1
            
    return DP[u], CN[u]

# 各頂点の真のDP値を求めていく

def bfs(u, p=-1):
    
    global DP, E
    
    tmp_ans = DP[u]
    tmp_cn = 1
    
    for v in E[u]:  # 各vに対して「真のDP値」を求めていく
        if v == p:
            continue
            
        # DP[u] と DP[v] から DP[v <- u] を求める
        tmp_cn = N - CN[v]  # v から見たときの u の部分木の要素数
        # print(v+1,tmp_cn)
        tmp_ans = DP[u] // DP[v] // cmb(N - 1, CN[v])
                
        # DP[u <- v] を使って、DP[v] を更新する
        DP[v] = DP[v] * tmp_ans * cmb(N-1, tmp_cn) % MOD
        bfs(v, u)
    
    return

# 入力処理
N = int(input())  # 頂点数
E = [[] for _ in range(N)]  # 辺の情報

for _ in range(N - 1):
    a, b = map(int, input().split())
    E[a-1].append(b-1)  # 双方向の情報
    E[b-1].append(a-1)
    
DP = [ModInt(1)] * N
CN = [0] * N

dfs(0)
bfs(0)

for i in DP:
    print(i)

Buggy submission (verdict: Runtime Error):
import sys
sys.setrecursionlimit(10**6)

# 組み合わせ
mod = 10 ** 9 + 7
N = 2* 10 ** 5  # N は必要分だけ用意する
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用

for i in range(2, N + 1):
    fact.append((fact[-1] * i) % mod)
    inv.append((-inv[mod % i] * (mod // i)) % mod)
    factinv.append((factinv[-1] * inv[-1]) % mod)

def cmb(n, r):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n-r] % mod
  
# 深さ優先探索
def dfs(v, p=-1):
    
    dp_l = 1  # 自分自身しかない場合
    size_l = 1 # 自分自身のサイズを含める

    # 子の情報をあわせて数え上げる
    for u in E[v]:
        
        # 親へのルートは辿らない
        if u == p:
            continue

        d, s = dfs(u, v)
        d %= mod
        size_l += s
        dp_l = dp_l * d * cmb(size_l-1, s) % mod

    dp[v] = dp_l
    size[v] = size_l
        
    return (int(dp_l), size_l)
  
def bfs(v, p=-1):
    
    for u in E[v]:
        if u == p:
            continue
        
        # u がなくなった場合の dp[v] 値、 size を求める
        # 一旦、uを切り離す

        o_size = size[v] - size[u]

        partial_v = int(dp[v] / dp[u] / cmb(N - 1, size[u]))
        
        # print(partial_v, dp[u])
        
        # u に v 側の部分木が接続された場合の値を求める
        # u に v を根とする部分木をつける

        dp_l = dp[u] * partial_v * cmb(N-1, size[u]-1) % mod
        
        dp[u] = dp_l % mod
    
        bfs(u,v)
        
# 入力処理
# N = int(input())
# E = [[] for _ in range(N)]

# for _ in range(N-1):
#     a, b = map(int, input().split())
#     E[a-1].append(b-1)
#     E[b-1].append(a-1)
      
dp = [1] * N
size = [1] * N


dfs(0)

bfs(0)

for i in range(N):
    print(dp[i])

Buggy submission (verdict: Runtime Error):
import math
import sys
sys.setrecursionlimit(10**6)

# 組み合わせ
mod = 10 ** 9 + 7
N = 10 ** 6  # N は必要分だけ用意する
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用

for i in range(2, N + 1):
    fact.append((fact[-1] * i) % mod)
    inv.append((-inv[mod % i] * (mod // i)) % mod)
    factinv.append((factinv[-1] * inv[-1]) % mod)

def cmb(n, r):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n-r] % mod

# 深さ優先探索
def dfs(v, p=-1):
    
    dp_l = 1  # 自分自身しかない場合
    size_l = 1 # 自分自身のサイズを含める

    # 子の情報をあわせて数え上げる
    for u in E[v]:
        
        # 親へのルートは辿らない
        if u == p:
            continue

        d, s = dfs(u, v)
        d %= mod
        size_l += s

        comb = int(math.factorial(size_l - 1) / (math.factorial((size_l - 1) - s)) / (math.factorial(s)))
        dp_l = dp_l * d * comb

    dp[v] = dp_l
    size[v] = size_l
        
    return (int(dp_l), size_l)

  
def bfs(v, p=-1):
    
    for u in E[v]:
        if u == p:
            continue
        
        # u がなくなった場合の dp[v] 値、 size を求める
        # 一旦、uを切り離す

        o_size = size[v] - size[u]

        partial_v = int(dp[v] / dp[u] / cmb(N - 1, size[u]))
        
        # u に v 側の部分木が接続された場合の値を求める
        # u に v を根とする部分木をつける

        dp_l = dp[u] * partial_v * cmb(N-1, size[u]-1)
        
        dp[u] = dp_l
    
        bfs(u,v)

# 入力処理
N = int(input())
E = [[] for _ in range(N)]

for _ in range(N-1):
    a, b = map(int, input().split())
    E[a-1].append(b-1)
    E[b-1].append(a-1)
      
dp = [1] * N
size = [1] * N

dfs(0)
bfs(0)

for i in range(N):
    print(dp[i])

Buggy submission (verdict: Runtime Error):
import math
import sys
sys.setrecursionlimit(10**6)

# 組み合わせ
mod = 10 ** 9 + 7
N = 10 ** 6  # N は必要分だけ用意する
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用

for i in range(2, N + 1):
    fact.append((fact[-1] * i) % mod)
    inv.append((-inv[mod % i] * (mod // i)) % mod)
    factinv.append((factinv[-1] * inv[-1]) % mod)

def cmb(n, r):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n-r] % mod

# 深さ優先探索
def dfs(v, p=-1):
    
    dp_l = 1  # 自分自身しかない場合
    size_l = 1 # 自分自身のサイズを含める

    # 子の情報をあわせて数え上げる
    for u in E[v]:
        
        # 親へのルートは辿らない
        if u == p:
            continue

        d, s = dfs(u, v)
        d %= mod
        size_l += s

        comb = int(math.factorial(size_l - 1) / (math.factorial((size_l - 1) - s)) / (math.factorial(s)))
        dp_l = dp_l * d * comb

    dp[v] = dp_l
    size[v] = size_l
        
    return (int(dp_l), size_l)

  
def bfs(v, p=-1):
    
    for u in E[v]:
        if u == p:
            continue
        
        # u がなくなった場合の dp[v] 値、 size を求める
        # 一旦、uを切り離す

        o_size = size[v] - size[u]

        partial_v = int(dp[v] / dp[u] / cmb(N - 1, size[u]))
        
        # u に v 側の部分木が接続された場合の値を求める
        # u に v を根とする部分木をつける

        dp_l = dp[u] * partial_v * cmb(N-1, size[u]-1)
        
        dp[u] = dp_l
    
        bfs(u,v)

# 入力処理
N = int(input())
E = [[] for _ in range(N)]

for _ in range(N-1):
    a, b = map(int, input().split())
    E[a-1].append(b-1)
    E[b-1].append(a-1)
      
dp = [0] * N
size = [0] * N

dfs(0)
bfs(0)

for i in range(N):
    print(dp[i])

Buggy submission (verdict: Runtime Error):
import math
import sys
sys.setrecursionlimit(10**6)

# 組み合わせ
mod = 10 ** 9 + 7
N = 10 ** 6  # N は必要分だけ用意する
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用

for i in range(2, N + 1):
    fact.append((fact[-1] * i) % mod)
    inv.append((-inv[mod % i] * (mod // i)) % mod)
    factinv.append((factinv[-1] * inv[-1]) % mod)

def cmb(n, r):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n-r] % mod

N = int(input())
E = [[] for _ in range(N)]

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

# 深さ優先探索
def dfs(v, p=-1):
    
    dp_l = 1  # 自分自身しかない場合
    size_l = 1 # 自分自身のサイズを含める

    # 子の情報をあわせて数え上げる
    for u in E[v]:
        
        # 親へのルートは辿らない
        if u == p:
            continue

        d, s = dfs(u, v)
        d %= mod
        size_l += s

        comb = int(math.factorial(size_l - 1) / (math.factorial((size_l - 1) - s)) / (math.factorial(s)))
        dp_l = dp_l * d * comb

    dp[v] = dp_l
    size[v] = size_l
        
    return (int(dp_l), size_l)
  
def bfs(v, p=-1):
    
    for u in E[v]:
        if u == p:
            continue
        
        o_size = size[v] - size[u]

        tmp = int(dp[v] / dp[u] / (math.factorial(N - 1) / (math.factorial(size[u]) * math.factorial(N - 1 - size[u]))))
        
        # comb = int(math.factorial((size[u] - 1) + (N - size[u])) / (math.factorial(size[u] - 1) * math.factorial(N - size[u])))
        comb = int(math.factorial(N - 1) / (math.factorial(size[u] - 1) * math.factorial(N - size[u])))
        dp_l = dp[u] * tmp * comb
        
        dp[u] = dp_l
    
        bfs(u,v)

dp = [0] * N
size = [0] * N

dfs(0)
bfs(0)

for i in range(N):
    print(dp[i])

Buggy submission (verdict: Runtime Error):
import math

mod = 10**9 + 7

N = int(input())
E = [[] for _ in range(N)]

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

# 深さ優先探索
def dfs(v, p=-1):
    
    dp_l = 1  # 自分自身しかない場合
    size_l = 1 # 自分自身のサイズを含める

    # 子の情報をあわせて数え上げる
    for u in E[v]:
        
        # 親へのルートは辿らない
        if u == p:
            continue

        d, s = dfs(u, v)
        d %= mod
        size_l += s

        comb = int(math.factorial(size_l - 1) / (math.factorial((size_l - 1) - s)) / (math.factorial(s)))
        dp_l = dp_l * d * comb

    dp[v] = dp_l
    size[v] = size_l
        
    return (int(dp_l), size_l)
  
def bfs(v, p=-1):
    
    for u in E[v]:
        if u == p:
            continue
        
        o_size = size[v] - size[u]

        tmp = int(dp[v] / dp[u] / (math.factorial(N - 1) / (math.factorial(size[u]) * math.factorial(N - 1 - size[u]))))
        
        # comb = int(math.factorial((size[u] - 1) + (N - size[u])) / (math.factorial(size[u] - 1) * math.factorial(N - size[u])))
        comb = int(math.factorial(N - 1) / (math.factorial(size[u] - 1) * math.factorial(N - size[u])))
        dp_l = dp[u] * tmp * comb
        
        dp[u] = dp_l
    
        bfs(u,v)

dp = [0] * N
size = [0] * N

dfs(0)
bfs(0)

for i in range(N):
    print(dp[i])