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:



Sample input:
3
1 2
1 3


Sample output:
2
1
1

Submission status: Accepted

Solution code:
def main():
    import sys
    from collections import deque

    input = sys.stdin.readline
    sys.setrecursionlimit(1000000)

    n = int(input())
    f = 0

    E = [[] for i in range(n)]
    for i in range(n-1):
        a, b = map(int, input().split())
        E[a-1].append(b-1)
        E[b-1].append(a-1)
        if len(E[a-1]) > n // 10 or len(E[b-1]) > n // 10:
            f = 1

    mod = 10 ** 9 + 7
    N = n + 1

    #逆元テーブル
    inv_t = [0]+[1]
    for i in range(2, N):
        inv_t += [inv_t[mod % i] * (mod - int(mod / i)) % mod]

    #階乗計算
    kai = [1, 1]
    rev_kai = [1, inv_t[1]]
    for i in range(2, N):
        kai.append(kai[-1] * i % mod)
        rev_kai.append(rev_kai[-1] * inv_t[i] % mod)

    # コンビネーション計算
    def cmb(n, r):
        if n == 0 or r == 0:
            return 1
        else:
            return kai[n] * rev_kai[r] * rev_kai[n-r] % mod

    down = [{} for i in range(n+1)]
    up = [0 for i in range(n+1)]
    down_sum = [0 for i in range(n)]
    down_mul = [{} for i in range(n)]

    def dfs_down(cur, pre):
        if E[cur] == [pre]:
            down[pre][cur] = [1, 1]
        ns = []
        cnt = 1
        ns_append = ns.append
        for e in E[cur]:
            if e != pre:
                if e not in down[cur]:
                    dfs_down(e, cur)
                ni, cnti = down[cur][e]
                ns_append(ni)
                cnt = cnt * cnti % mod
        s = sum(ns)
        S = s
        for ni in ns:
            cnt = cnt * cmb(s, ni) % mod
            s -= ni
        down[pre][cur] = [S+1, cnt]
    
    def preprocess():
        for i in range(n):
            ns = []
            cnt = 1
            cnts = []
            l = [1]
            r = [1]
            cnts_append = cnts.append
            ns_append = ns.append
            l_append = l.append
            r_append = r.append
            downi = down[i]
            downmuli = down_mul[i]
            for e in downi:
                ni, cnti = downi[e]
                ns_append(ni)
                cnts_append(cnti)
            for j in range(len(cnts)):
                l_append(l[-1] * cnts[j] % mod)
                r_append(r[-1] * cnts[-j-1] % mod)
            for j, e in enumerate(downi):
                if len(r) >= 2:
                    downmuli[e] = l[j] * r[-j-2] % mod
                else:
                    downmuli[e] = 1

            s = sum(ns)
            S = s
            for ni in ns:
                cnt = cnt * cmb(s, ni) % mod
                s -= ni
            down_sum[i] = [S, cnt, l[-1]]
    
    def dfs_up_preprocess(cur, pre):
        stack = deque([[cur, pre]])
        while stack:
            cur, pre = stack.pop() 
            if cur != 0:
                ni = 0
                cnt = 1
                if up[pre]:
                    ni, cnt = up[pre]
                # 自分以外の子について計算
                # あらかじめ積をとっておけば、毎回for 文回さなくて良い
                n_cur, cnt_cur = down[pre][cur]
                n_sum, cnt_sum, _ = down_sum[pre]
                cnt = cnt * down_mul[pre][cur] % mod
                cnt = cnt * cnt_sum % mod
                cnt = cnt * kai[n_sum - n_cur] % mod
                cnt = cnt * kai[n_cur] % mod
                cnt = cnt * rev_kai[n_sum] % mod
                cnt = cnt * cmb(n_sum-n_cur+ni, ni) % mod
                s = n_sum-n_cur+ni

                up[cur] = [s+1, cnt]
            for e in E[cur]:
                if e != pre:
                    stack.append([e, cur])

    def dfs_up(cur, pre):
        stack = deque([[cur, pre]])
        while stack:
            cur, pre = stack.pop() 
            if cur != 0:
                ns = []
                cnt = 1
                ns_append = ns.append
                if up[pre]:
                    ni, cnti = up[pre]
                    ns_append(ni)
                    cnt = cnt * cnti % mod
                bros = down[pre]
                for bro in bros:
                    if bro != cur:
                        ni, cnti = bros[bro]
                        ns_append(ni)
                        cnt = cnt * cnti % mod
                s = sum(ns)
                S = s
                for ni in ns:
                    cnt = cnt * cmb(s, ni) % mod
                    s -= ni
                up[cur] = [S+1, cnt]
            for e in E[cur]:
                if e != pre:
                    stack.append([e, cur])


    if f:
        dfs_down(0, n)
        preprocess()
        dfs_up_preprocess(0, n)


        for i in range(n):
            ni = 0
            cnt = 1
            if up[i]:
                ni, cnt = up[i]
            n_sum, cnt_sum, cnt_all = down_sum[i]
            cnt = cnt * cnt_sum % mod
            cnt = cnt * cnt_all % mod
            cnt = cnt * cmb(n_sum + ni, ni) % mod
            print(cnt)
    else:
        
        dfs_down(0, n)
        dfs_up(0, n)


        for i in range(n):
            ns = []
            cnt = 1
            ns_append = ns.append
            if up[i]:
                ni, cnti = up[i]
                ns_append(ni)
                cnt = cnt * cnti % mod
            for bro in down[i]:
                ni, cnti = down[i][bro]
                ns_append(ni)
                cnt = cnt * cnti % mod
            s = sum(ns)
            for ni in ns:
                cnt = cnt * cmb(s, ni) % mod
                s -= ni
            print(cnt)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
input=sys.stdin.readline
from collections import deque

def main():
    mod=1000000007
    inv=lambda x: pow(x,mod-2,mod)    
    n=int(input())
    Fact=[1]
    for i in range(1,n+1):
        Fact.append(Fact[i-1]*i%mod)
    Finv=[0]*(n+1)
    Finv[-1]=inv(Fact[-1])
    for i in range(n-1,-1,-1):
        Finv[i]=Finv[i+1]*(i+1)%mod
    Edges=[[] for _ in range(n)]
    for _ in range(n-1):
        a,b=map(int,input().split())
        a-=1; b-=1
        Edges[a].append(b)
        Edges[b].append(a)
    Stack=[0]
    Par=[-1]*n
    Order=[]
    while Stack:
        v=Stack.pop()
        Order.append(v)
        for c in Edges[v]:
            if c!=Par[v]:
                Stack.append(c)
                Par[c]=v
    DP=[1]*n
    Size=[1]*n
    for v in Order[::-1]:
        DP[v]*=Fact[Size[v]-1]
        DP[v]%=mod
        p=Par[v]
        if p==-1:
            continue
        Size[p]+=Size[v]
        DP[p]*=DP[v]*Finv[Size[v]]
        DP[p]%=mod
    Ans=[0]*n
    que=deque()
    que.append((0,-1,1))
    while que:
        v,par,par_cnt=que.popleft()
        Left=[1]
        for to in Edges[v]:
            tmp=DP[to]*Finv[Size[to]]
            if to==par:
                tmp=par_cnt*Finv[n-Size[v]]
            Left.append(Left[-1]*tmp%mod)
        Right=[1]
        for to in reversed(Edges[v]):
            tmp=DP[to]*Finv[Size[to]]
            if to==par:
                tmp=par_cnt*Finv[n-Size[v]]
            Right.append(Right[-1]*tmp%mod)
        Ans[v]=Left[-1]*Fact[n-1]%mod
        m=len(Edges[v])
        for i,to in enumerate(Edges[v]):
            if to!=par:
                que.append((to,v,Left[i]*Right[m-i-1]*Fact[n-Size[to]-1]%mod))
    print(*Ans,sep="\n")
    
if __name__=='__main__':
    main()

Submission status: Accepted

Solution code:
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

N = INT()
lim = N+10  # 必要そうな階乗の限界を入れる
fact = [1] * (lim+1)
fact_inv = [1] * (lim+1)
for n in range(1, lim+1):
    fact[n] = (fact[n-1] * n) % mod
fact_inv[lim] = pow(fact[lim], mod-2, mod)
for n in range(lim, 0, -1):
    fact_inv[n-1] = (n * fact_inv[n]) % mod

tree = [[] for _ in range(N+1)]  # 1-indexed
for _ in range(N-1):
	a, b = MAP()
	tree[a].append(b)
	tree[b].append(a)

root = 1
parent = [0]*(N+1)
order = []
stack = [root]
while stack:
    x = stack.pop()
    order.append(x)
    for y in tree[x]:
        if y == parent[x]:
            continue
        parent[y] = x
        stack.append(y)

size_d = [0]*(N+1)
dp_d = [1]*(N+1)

for v in order[::-1]:  # 根に遠いほうから(down方向のボトムアップ)
    dp_d[v] *= fact[size_d[v]]
    dp_d[v] %= mod
    p = parent[v]
    s = size_d[v] + 1
    size_d[p] += s
    dp_d[p] *= fact_inv[s] * dp_d[v]
    dp_d[p] %= mod

size_u = [N-1-x for x in size_d]
dp_u = [1]*(N+1)

def merge(p1, p2):
    den_inv1, v1 = p1
    den_inv2, v2 = p2
    return den_inv1*den_inv2%mod, v1*v2%mod

for v in order:
    p = parent[v]
    arr = [(fact_inv[size_d[node]+1], dp_d[node]) if node != p else (fact_inv[size_u[v]], dp_u[v]) for node in tree[v]]
    left = [(1, 1)] + list(accumulate(arr, merge))[:-1]
    right = list(accumulate(arr[::-1], merge))[-2::-1] + [(1, 1)]
    contrib = [merge(x, y) for x, y in zip(left, right)]
    for node, c in zip(tree[v], contrib):
        if node != p:
            dp_u[node] = (((c[0]*c[1])%mod)*fact[size_u[node]-1])%mod
# print(dp_u)
for xd, xu, sd, su in zip(dp_d[1:], dp_u[1:], size_d[1:], size_u[1:]):
    x = xd * xu * fact[sd + su] * fact_inv[sd] * fact_inv[su] % mod
    print(x)

Submission status: Accepted

Solution code:
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

N = INT()
lim = N+10  # 必要そうな階乗の限界を入れる
fact = [1] * (lim+1)
fact_inv = [1] * (lim+1)
for n in range(1, lim+1):
    fact[n] = (fact[n-1] * n) % mod
fact_inv[lim] = pow(fact[lim], mod-2, mod)
for n in range(lim, 0, -1):
    fact_inv[n-1] = (n * fact_inv[n]) % mod

tree = [[] for _ in range(N+1)]  # 1-indexed
for _ in range(N-1):
	a, b = MAP()
	tree[a].append(b)
	tree[b].append(a)

root = 1
parent = [0]*(N+1)
order = []
stack = [root]
while stack:
    x = stack.pop()
    order.append(x)
    for y in tree[x]:
        if y == parent[x]:
            continue
        parent[y] = x
        stack.append(y)

size_d = [0]*(N+1)
dp_d = [1]*(N+1)

for v in order[::-1]:  # 根に遠いほうから(down方向のボトムアップ)
    dp_d[v] *= fact[size_d[v]]
    dp_d[v] %= mod
    p = parent[v]
    s = size_d[v] + 1
    size_d[p] += s
    dp_d[p] *= fact_inv[s] * dp_d[v]
    dp_d[p] %= mod

size_u = [N-1-x for x in size_d]
dp_u = [1]*(N+1)

def merge(p1, p2):
    den_inv1, v1 = p1
    den_inv2, v2 = p2
    return den_inv1*den_inv2%mod, v1*v2%mod

for v in order:
    p = parent[v]
    arr = [(fact_inv[size_d[node]+1], dp_d[node]) if node != p else (fact_inv[size_u[v]], dp_u[v]) for node in tree[v]]
    left = [(1, 1)] + list(accumulate(arr, merge))[:-1]
    right = list(accumulate(arr[::-1], merge))[-2::-1] + [(1, 1)]
    contrib = [merge(x, y) for x, y in zip(left, right)]
    for node, c in zip(tree[v], contrib):
        if node != p:
            dp_u[node] = (c[0]*c[1]*fact[size_u[node]-1])%mod
# print(dp_u)
for xd, xu, sd, su in zip(dp_d[1:], dp_u[1:], size_d[1:], size_u[1:]):
    x = xd * xu * fact[sd + su] * fact_inv[sd] * fact_inv[su] % mod
    print(x)

Submission status: Accepted

Solution code:
from collections import deque


mod = 10 ** 9 + 7
SIZE = 2 * 10 ** 5 + 1
fact = [0] * SIZE
inv = [0] * SIZE
finv = [0] * SIZE
fact[0], fact[1] = 1, 1
inv[1] = 1
finv[0], finv[1] = 1, 1
for i in range(2, SIZE):
    fact[i] = fact[i - 1] * i % mod
    inv[i] = mod - inv[mod % i] * (mod // i) % mod
    finv[i] = finv[i - 1] * inv[i] % mod


def nCr(n, r):
    if n < 0 or r < 0 or n < r:
        return 0
    return fact[n] * (finv[r] * finv[n - r] % mod) % mod


n = int(input())
edges = [[] for _ in range(n)]

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

root_to_leaf = []
parents = [0] * n

todo = deque([])
for to in edges[0]:
    todo.append([to, 0])

while todo:
    node, parent = todo.popleft()
    root_to_leaf.append(node)
    parents[node] = parent

    for to in edges[node]:
        if to == parent:
            continue
        todo.append([to, node])

size_of_subtree = [0] * n
pattern_in_subtree = [1] * n

for node in root_to_leaf[::-1]:
    parent = parents[node]
    size_of_subtree[node] += 1
    size_of_subtree[parent] += size_of_subtree[node]
    pattern_in_subtree[parent] *= nCr(size_of_subtree[parent], size_of_subtree[node]) * pattern_in_subtree[node] % mod
    pattern_in_subtree[parent] %= mod

answers = [0] * n
answers[0] = pattern_in_subtree[0]

for node in root_to_leaf:
    parent = parents[node]
    ans = answers[parent] * size_of_subtree[node] * inv[n - size_of_subtree[node]] % mod
    answers[node] = ans

for ans in answers:
    print(ans)

Submission status: Accepted

Solution code:
class ReRooting:
    def __init__(self, size, root, identDp=0, identCum=0):
        self.size = size
        self.edges = [[] for _ in range(self.size + 1)]
        self.root = root
        self.identDp = identDp
        self.identCum = identCum

    def addEdge(self, fr, to):
        self.edges[fr].append(to)
        self.edges[to].append(fr)

    # 根を固定したときの木DP
    def lift(self, top, bottom):
        return (((top[0] * bottom[0]) % MOD * comb.ncr(top[1] + bottom[1] + 1, top[1])) % MOD, top[1] + bottom[1] + 1)

    # 子の累積
    def merge(self, cum, a):
        return (((cum[0] * a[0]) % MOD * comb.ncr(cum[1] + a[1], cum[1])) % MOD, cum[1] + a[1])

    def sol(self):
        # 普通に木DPをする
        # 並行して各頂点につき、子の値の累積liftを左右から求めておく
        # その後根から順番に、親からの寄与を求めていく(fromParent)
        N = self.size
        edges = self.edges

        st = [self.root]
        parent = [-1] * (N + 1)
        child = [[] for _ in range(N + 1)]
        order = []
        while st:
            v = st.pop()
            order.append(v)
            for to in edges[v]:
                if parent[v] == to:
                    continue
                parent[to] = v
                child[v].append(to)
                st.append(to)

        dp = [self.identDp] * (N + 1)
        left = [self.identCum] * (N + 1)
        right = [self.identCum] * (N + 1)
        for v in order[::-1]:
            tmp = self.identCum
            for ch in child[v]:
                left[ch] = tmp
                tmp = self.lift(tmp, dp[ch])
            tmp = self.identCum
            for ch in reversed(child[v]):
                right[ch] = tmp
                tmp = self.lift(tmp, dp[ch])
            dp[v] = tmp

        fromParent = [self.identDp] * (N + 1)
        for v in order:
            if v == self.root:
                continue
            fromParent[v] = self.lift(self.merge(left[v], right[v]), fromParent[parent[v]])
            dp[v] = self.lift(dp[v], fromParent[v])

        return dp[:N]

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]

N = int(input())
MOD = 10**9 + 7
comb = Combination(2 * 10**5 + 100)

tree = ReRooting(N, 0, (1, -1), (1, 0))

for _ in range(N - 1):
    fr, to = map(int, input().split())
    tree.addEdge(fr - 1, to - 1)

ans = tree.sol()
print(*[a for a, b in ans], sep='\n')

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(1234567890)
from collections import deque

n, *L = map(int, open(0).read().split())
mod = 10 ** 9 + 7


def prepare(m, mod=10 ** 9 + 7):
	fac = [1] * (m + 1)
	inv = [1] * (m + 1)
	for i in range(1, m + 1):
		fac[i] = fac[i - 1] * i % mod
	inv[-1] = pow(fac[-1], mod - 2, mod)
	for i in range(m - 1, -1, -1):
		inv[i] = inv[i + 1] * (i + 1) % mod
	return fac, inv


fac, inv = prepare(n)

con = [[] for _ in range(n)]
for s, t in zip(*[iter(L)] * 2):
	con[s - 1] += t - 1,
	con[t - 1] += s - 1,

par = [-1] * n
q = deque([0])
odr = []
while q:
	cur = q.popleft()
	odr += cur,
	for nxt in con[cur]:
		if nxt != par[cur]:
			par[nxt] = cur
			q.append(nxt)

sz = [1] * (n + 1)
st = 1
for i in odr[::-1]:
	sz[par[i]] += sz[i]
	st *= pow(sz[i], mod - 2, mod)
	st %= mod

# inv[n-1]*fac[sz[i]]*inv[sz[i]-1]*inv[n-sz[i]]*fac[n-sz[i]-1]*fac[n-1]=sz[i]*(n-sz[i])^-1
ans = [st * fac[n] % mod] + [0] * (n - 1)
for i in odr[1:]:
	ans[i] = ans[par[i]] * sz[i] % mod * pow(n - sz[i], mod - 2, mod) % mod
print(*ans)

Submission status: Accepted

Solution code:
from functools import *
from itertools import *
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.buffer.readline
 
M = 10**9+7
N = int(input())

@lru_cache(maxsize=None)
def mod_inv(x):
  return 1 if x == 1 else M // x * -mod_inv(M%x) % M

Weight = [0]*(N+1)
Size = [0]*(N+1)
def calc_subtree(v):
  W, S = 1, 1
  for child in Edge[v]:
    Edge[child].remove(v)
    calc_subtree(child)
    W = W * Weight[child] % M
    S += Size[child]
  Weight[v] = W * S % M
  Size[v] = S

Ans = [0]*(N+1)
def calc_ans(v, a):
  Ans[v] = a
  for child in Edge[v]:
    n = Size[child]
    calc_ans(child, a * n * mod_inv(N-n) % M)

Edge = [set() for i in range(N+1)]
fact = N
for i in range(1, N):
  fact = fact * i % M
  a, b = map(int, input().split())
  Edge[a].add(b)
  Edge[b].add(a)
  
calc_subtree(1)
calc_ans(1, mod_inv(Weight[1]) * fact % M)

for a in islice(Ans, 1, None):
  print(a)

Submission status: Accepted

Solution code:
from functools import *
from itertools import *
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.buffer.readline
 
M = 10**9+7
N = int(input())

@lru_cache(maxsize=None)
def mod_inv(x):
  return 1 if x == 1 else M // x * -mod_inv(M%x) % M

Weight = [0]*(N+1)
Size = [0]*(N+1)
def calc_subtree(v):
  W, S = 1, 1
  for child in Edge[v]:
    Edge[child].remove(v)
    w, s = calc_subtree(child)
    W = W * w % M
    S += s
  Weight[v] = W * S % M
  Size[v] = S
  return Weight[v], Size[v]

Ans = [0]*(N+1)
def calc_ans(v, a):
  Ans[v] = a
  for child in Edge[v]:
    n = Size[child]
    calc_ans(child, a * n * mod_inv(N-n) % M)

Edge = [set() for i in range(N+1)]
fact = N
for i in range(1, N):
  fact = fact * i % M
  a, b = map(int, input().split())
  Edge[a].add(b)
  Edge[b].add(a)
  
calc_subtree(1)
calc_ans(1, mod_inv(Weight[1]) * fact % M)

for a in islice(Ans, 1, None):
  print(a)

Submission status: Accepted

Solution code:
from functools import *
from itertools import *
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.buffer.readline
 
M = 10**9+7
N = int(input())

@lru_cache(maxsize=None)
def mod_inv(x):
  return 1 if x == 1 else M // x * -mod_inv(M%x) % M

Weight = [0]*(N+1)
Size = [0]*(N+1)
def calc_subtree(v):
  W, S = 1, 1
  for child in Edge[v]:
    Edge[child].remove(v)
    w, s = calc_subtree(child)
    W = W * w % M
    S += s
  Weight[v] = W * mod_inv(S) % M
  Size[v] = S
  return Weight[v], Size[v]

Ans = [0]*(N+1)
def calc_ans(v, a):
  Ans[v] = a
  for child in Edge[v]:
    n = Size[child]
    calc_ans(child, a * n * mod_inv(N-n) % M)

Edge = [set() for i in range(N+1)]
fact = N
for i in range(1, N):
  fact = fact * i % M
  a, b = map(int, input().split())
  Edge[a].add(b)
  Edge[b].add(a)
  
calc_subtree(1)
calc_ans(1, Weight[1] * fact % M)

for a in islice(Ans, 1, None):
  print(a)

Submission status: Accepted

Solution code:
from functools import *
from itertools import *
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.buffer.readline
 
M = 10**9+7
N = int(input())

@lru_cache(maxsize=None)
def mod_inv(x):
  return 1 if x == 1 else M // x * -mod_inv(M%x) % M

Weight = [0]*(N+1)
Size = [0]*(N+1)
def calc_subtree(v):
  W, S = 1, 1
  for child in Edge[v]:
    Edge[child].remove(v)
    w, s = calc_subtree(child)
    W = W * w % M
    S += s
  Weight[v] = W * S % M
  Size[v] = S
  return Weight[v], Size[v]

Ans = [0]*(N+1)
def calc_ans(v, a):
  Ans[v] = a
  for child in Edge[v]:
    n = Size[child]
    calc_ans(child, Ans[v] * n * mod_inv(N-n) % M)

Edge = [set() for i in range(N+1)]
fact = N
for i in range(1, N):
  fact = fact * i % M
  a, b = map(int, input().split())
  Edge[a].add(b)
  Edge[b].add(a)
  
calc_subtree(1)
calc_ans(1, mod_inv(Weight[1]) * fact % M)

for a in islice(Ans, 1, None):
  print(a)

Submission status: Accepted

Solution code:
from functools import *
from collections import *
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.buffer.readline
 
M = 10**9+7
N = int(input())

@lru_cache(maxsize=None)
def mod_inv(x):
  if x == 1:
    return 1
  return M // x * -mod_inv(M%x) % M

weight = [0]*(N+1)
size = [0]*(N+1)
def calc_subtree(v):
  W = 1
  S = 1
  for child in Edge[v]:
    Edge[child].remove(v)
    w, s = calc_subtree(child)
    W = W * w % M
    S += s
  weight[v] = W * S % M
  size[v] = S
  return weight[v], size[v]

ans = [0]*(N+1)
def set_ans(v, a):
  ans[v] = a
  for child in Edge[v]:
    n = size[child]
    set_ans(child, ans[v] * n * mod_inv(N-n) % M)

Edge = defaultdict(set)
fact = N
for i in range(1, N):
  fact = fact * i % M
  a, b = map(int, input().split())
  Edge[a].add(b)
  Edge[b].add(a)
  
calc_subtree(1)
set_ans(1, mod_inv(weight[1]) * fact % M)
for i in range(1, N+1):
  print(ans[i])

Submission status: Accepted

Solution code:
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

N = INT()
lim = N+10  # 必要そうな階乗の限界を入れる
fact = [1] * (lim+1)
fact_inv = [1] * (lim+1)
for n in range(1, lim+1):
    fact[n] = (fact[n-1] * n) % mod
fact_inv[lim] = pow(fact[lim], mod-2, mod)
for n in range(lim, 0, -1):
    fact_inv[n-1] = (n * fact_inv[n]) % mod

tree = [[] for _ in range(N+1)]  # 1-indexed
for _ in range(N-1):
	a, b = MAP()
	tree[a].append(b)
	tree[b].append(a)

root = 1
parent = [0] * (N + 1)
order = []
stack = [root]
while stack:
    x = stack.pop()
    order.append(x)
    for y in tree[x]:
        if y == parent[x]:
            continue
        parent[y] = x
        stack.append(y)
 
size_d = [0] * (N + 1)
dp_d = [1] * (N + 1)

for v in order[::-1]:  # 根に遠いほうから(down方向のボトムアップ)
    dp_d[v] *= fact[size_d[v]]
    dp_d[v] %= mod
    p = parent[v]
    s = size_d[v] + 1
    size_d[p] += s
    dp_d[p] *= fact_inv[s] * dp_d[v]
    dp_d[p] %= mod
size_u = [N - 1 - x for x in size_d]
dp_u = [1] * (N + 1)

for v in order[1:]:  # 根に近いほうから(up方向のトップダウン)
    p = parent[v]
    x = dp_d[p]
    x *= dp_u[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]-1]
    x *= fact_inv[size_u[p]]
    dp_u[v] = x % mod

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

Submission status: Accepted

Solution code:
from functools import *
from collections import *
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.buffer.readline
 
M = 10**9+7

@lru_cache(maxsize=None)
def mod_inv(x):
  if x == 1:
    return 1
  return M // x * -mod_inv(M%x) % M

@lru_cache(maxsize=None)
def calc_subtree(v):
  ret = 1
  size = 1
  for child in Edge[v]:
    Edge[child].remove(v)
    r, s = calc_subtree(child)
    ret = ret * r % M
    size += s
  ret = ret * size % M
  return ret, size

ans = {}
def set_ans(v, a):
  ans[v] = a
  for child in Edge[v]:
    n = calc_subtree(child)[1]
    set_ans(child, ans[v] * n * mod_inv(N-n) % M)

N = int(input())
Edge = defaultdict(set)
fact = N
for i in range(1, N):
  fact = fact * i % M
  a, b = map(int, input().split())
  Edge[a].add(b)
  Edge[b].add(a)

set_ans(1, mod_inv(calc_subtree(1)[0]) * fact % M)
for i in range(1, N+1):
  print(ans[i])

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(1234567890)

n, *L = map(int, open(0).read().split())
mod = 10 ** 9 + 7
con = [[] for _ in range(n + 1)]
sz = [1] * (n + 1)
par = [0] * (n + 1)

for s, t in zip(*[iter(L)] * 2):
	con[s] += t,
	con[t] += s,


def prepare(m, mod=10 ** 9 + 7):
	fac = [1] * (m + 1)
	inv = [1] * (m + 1)
	for i in range(1, m + 1):
		fac[i] = fac[i - 1] * i % mod
	inv[-1] = pow(fac[-1], mod - 2, mod)
	for i in range(m - 1, -1, -1):
		inv[i] = inv[i + 1] * (i + 1) % mod
	return fac, inv


fac, inv = prepare(n)


def dfs1(cur, pre):
	par[cur] = pre
	for nxt in con[cur]:
		if nxt != pre:
			dfs1(nxt, cur)
			sz[cur] += sz[nxt]
			dp1[cur] *= dp1[nxt] * inv[sz[nxt]] % mod
			dp1[cur] %= mod
	dp1[cur] *= fac[sz[cur] - 1]
	dp1[cur] %= mod


def dfs2(cur, pre):
	dp2[cur] *= dp1[cur] * inv[sz[cur] - 1] % mod
	dp2[cur] %= mod
	dp2[cur] *= fac[n - 1]
	dp2[cur] %= mod
	for nxt in con[cur]:
		if nxt != pre:
			dp2[nxt] = fac[sz[nxt]] * pow(n - sz[nxt], mod - 2, mod) * pow(dp1[nxt], mod - 2, mod) * dp2[cur] * inv[n - 1] % mod
			dfs2(nxt, cur)


dp1 = [1] * (n + 1)
dfs1(1, 0)
dp2 = [1] * (n + 1)
dfs2(1, 0)

print(*dp2[1:], sep="\n")

Submission status: Accepted

Solution code:
from functools import *
from collections import *
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.buffer.readline
 
M = 10**9+7

@lru_cache(maxsize=None)
def mod_inv(a):
  b, x, y = M, 1, 0
  while a != 1:
    (d, a), b = divmod(b, a), a
    x, y = y-d*x, x
  return x%M

@lru_cache(maxsize=None)
def calc_subtree(v):
  ret = 1
  size = 1
  for child in Edge[v]:
    Edge[child].remove(v)
    r, s = calc_subtree(child)
    ret = ret * r % M
    size += s
      
  ret = ret * size % M
  return ret, size

ans = {}
def set_ans(v, a):
  ans[v] = a
  for child in Edge[v]:
    n = calc_subtree(child)[1]
    set_ans(child, ans[v] * n * mod_inv(N-n) % M)

N = int(input())
Edge = defaultdict(set)
fact = N
for i in range(1, N):
  fact = fact * i % M
  a, b = map(int, input().split())
  Edge[a].add(b)
  Edge[b].add(a)

set_ans(1, mod_inv(calc_subtree(1)[0]) * fact % M)
for i in range(1, N+1):
  print(ans[i])

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10**6)
def input():
	return sys.stdin.buffer.readline()[:-1]

MOD = 10**9 + 7
list_size = 200001

f_list = [1] * list_size
f_r_list = [1] * list_size

for i in range(list_size - 1):
	f_list[i + 1] = int((f_list[i] * (i + 2)) % MOD)

f_r_list[-1] = pow(f_list[-1], MOD - 2, MOD)

for i in range(2, list_size + 1):
	f_r_list[-i] = int((f_r_list[-i + 1] * (list_size + 2 - i)) % MOD)

def comb(n, r):
	if n < r:
		return 0
	elif n == 0 or r == 0 or n == r:
		return 1
	else:
		return (((f_list[n - 1] * f_r_list[n - r - 1]) % MOD) * f_r_list[r - 1]) % MOD 

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


dp_pat = [0 for _ in range(n)]
dp_num = [0 for _ in range(n)]


def dfs1(x, p):
	num = 0
	res = 1
	for v in adj[x]:
		if v == p:
			continue
		dfs1(v, x)
		num += dp_num[v]
		res *= comb(num, dp_num[v]) * dp_pat[v]
		res %= MOD
	dp_num[x] = num+1
	dp_pat[x] = res
	return

dfs1(0, -1)
ans = [0 for _ in range(n)]
ans[0] = dp_pat[0]

def dfs2(x, p):
	for v in adj[x]:
		if v == p:
			continue
		pres = [dp_pat[x], dp_num[x], dp_pat[v], dp_num[v]]
		dp_pat[x] *= pow(comb(dp_num[x]-1, dp_num[v]) * dp_pat[v], MOD-2, MOD)
		dp_pat[x] %= MOD
		dp_num[x] -= dp_num[v]

		dp_pat[v] *= comb(dp_num[x] + dp_num[v] - 1, dp_num[x]) * dp_pat[x]
		dp_pat[v] %= MOD
		dp_num[v] += dp_num[x]
		ans[v] = dp_pat[v]
		dfs2(v, x)
		dp_pat[x], dp_num[x], dp_pat[v], dp_num[v] = pres
	return

dfs2(0, -1)
print(*ans, sep="\n")