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:
import sys
input = sys.stdin.readline

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

    mod = 10**9+7 #出力の制限
    N = 10**6
    g1 = [1, 1] # 元テーブル
    g2 = [1, 1] #逆元テーブル
    inverse = [0, 1] #逆元テーブル計算用テーブル

    for i in range( 2, N + 1 ):
        g1.append( ( g1[-1] * i ) % mod )
        inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
        g2.append( (g2[-1] * inverse[-1]) % mod )

    # topological sort
    s = []
    s.append(0)
    parent = [-1]*n
    order = []
    while s:
        v = s.pop()
        order.append(v)
        for u in g[v]:
            if u == parent[v]:
                continue
            parent[u] = v
            s.append(u)

    dp = [1]*n
    c = [0]*n
    order.reverse()
    for v in order:
        dp[v] *= g1[c[v]]
        dp[v] %= mod
        c[v] += 1
        if parent[v] == -1:
            continue
        c[parent[v]] += c[v]
        dp[parent[v]] *= (dp[v]*g2[c[v]])
        dp[parent[v]] %= mod

    order.reverse()
    ans = [0]*n
    for v in order:
        ans[v] = dp[v]
        for u in g[v]:
            if u == parent[v]:
                continue
            dp[u] *= ans[v]*g2[c[v]-1]*g1[c[v]-1-c[u]]*g1[c[u]]*pow(dp[u],(mod-2),mod)
            dp[u] *= g2[c[u]-1]
            dp[u] *= g1[c[v]-1]
            dp[u] *= g2[c[v]-c[u]]
            dp[u] %= mod
            c[u] = c[v]
    for i in range(n):
        print(ans[i]%mod)

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
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')

Submission status: Accepted

Solution code:
def main():
    M=10**9+7
    N=10**5*2
    fac=[0]*(N+1)
    fac[0]=b=1
    for i in range(1,N+1):fac[i]=b=b*i%M
    inv=[0]*(N+1)
    inv[N]=b=pow(fac[N],M-2,M)
    for i in range(N,0,-1):inv[i-1]=b=b*i%M
    n,*t=open(0).read().split()
    n=int(n)
    e=[[]for _ in range(n)]
    for a,b in zip(*[map(int,t)]*2):
        e[a-1]+=b-1,
        e[b-1]+=a-1,
    o=[]
    s=[0]
    f=[1]*n
    while s:
        v=s.pop()
        f[v]=0
        o+=v,
        l=[]
        for w in e[v]:
            if f[w]:
                l+=w,
                s+=w,
        e[v]=l
    sz1,sz2=[0]*n,[0]*n
    dp1,dp2=[0]*n,[0]*n
    c=[[]for _ in range(n)]
    for v in o[::-1]:
        s=b=1
        c1,c2=[1],[1]
        for w in e[v]:
            u=sz1[w]
            b=b*dp1[w]*inv[u]%M
            c1+=b,
            s+=u
        b=1
        for w in e[v][::-1]:
            b=b*dp1[w]*inv[sz1[w]]%M
            c2+=b,
        c[v]=c1,c2[-2::-1]
        sz1[v]=s
        dp1[v]=b*fac[s-1]%M
    # print(dp1)
    sz2[0]=1
    dp2[0]=1
    for v in o:
        l=len(e[v])
        c1,c2=c[v]
        uv=sz2[v]-1
        tv=dp2[v]*inv[uv]
        uv+=sz1[v]
        for w,l,r in zip(e[v],c1,c2):
            tw=l*r%M
            uw=uv-sz1[w]-1
            dp2[w]=tv*tw*fac[uw]%M
            sz2[w]=uw+2
    # print(dp2)
    a=[]
    for dp1,dp2,sz1,sz2 in zip(dp1,dp2,sz1,sz2):
        sz1-=1
        sz2-=1
        a+=str(dp1*dp2*inv[sz1]*inv[sz2]*fac[sz1+sz2]%M),
    print('\n'.join(a))
main()

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
import sys
from functools import reduce

MAX_INT = 2**62-1
sys.setrecursionlimit(10**7)

input = sys.stdin.readline

# @profile
MOD = 10**9 + 7


def mul_mod(*args, mod=MOD):
    return reduce(lambda a, b: a * b % mod, args)


def solve(g, f, fi, m):
    mul = mul_mod

    stack = [(0, 1)]
    pre_order = []
    n = len(g) - 1

    while stack:
        pre, cur = stack.pop()
        pre_order.append((pre, cur))

        for nxt in g[cur]:
            if nxt == pre:
                continue
            stack.append((cur, nxt))

    size = [1] * (n+1)
    dp = [1] * (n+1)

    for pre, cur in reversed(pre_order):
        dp[cur] = mul(dp[cur], f[size[cur]-1])
        dp[pre] = mul(dp[pre], dp[cur], fi[size[cur]])
        size[pre] += size[cur]

    ans = [1] * (n+1)
    ans[1] = dp[1]

    for pre, cur in pre_order[1:]:
        i = size[cur]
        temp = mul(ans[pre], f[n-i-1], fi[n-1], f[i], pow(dp[cur], m-2, m))
        ans[cur] = mul(f[n-1], temp, fi[n-i], dp[cur], fi[i-1])
    print(*ans[1:], sep='\n')


# @profile
def main():
    mul = mul_mod
    mod = MOD
    n = int(input())
    g = [[] for _ in range(n+1)]

    fact = [1] * (n+1)
    fact_inv = [0] * (n+1)

    for i in range(1, n+1):
        fact[i] = mul(fact[i-1], i)

    fact_inv[-1] = pow(fact[-1], mod-2, mod)

    for i in range(n)[::-1]:
        fact_inv[i] = mul(fact_inv[i+1], (i+1))

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

    solve(g, fact, fact_inv, mod)


if __name__ == "__main__":

    main()

Submission status: Accepted

Solution code:
def main():
    M=10**9+7
    N=10**5*2
    fac=[0]*(N+1)
    fac[0]=b=1
    for i in range(1,N+1):fac[i]=b=b*i%M
    inv=[0]*(N+1)
    inv[N]=b=pow(fac[N],M-2,M)
    for i in range(N,0,-1):inv[i-1]=b=b*i%M
    n,*t=open(0).read().split()
    n=int(n)
    e=[[]for _ in range(n)]
    for a,b in zip(*[map(int,t)]*2):
        e[a-1]+=b-1,
        e[b-1]+=a-1,
    o=[]
    s=[0]
    f=[1]*n
    while s:
        v=s.pop()
        f[v]=0
        o+=v,
        l=[]
        for w in e[v]:
            if f[w]:
                l+=w,
                s+=w,
        e[v]=l
    sz1,sz2=[0]*n,[0]*n
    dp1,dp2=[0]*n,[0]*n
    c=[[]for _ in range(n)]
    for v in o[::-1]:
        s=b=1
        c1,c2=[1],[1]
        for w in e[v]:
            u=sz1[w]
            b=b*dp1[w]*inv[u]%M
            c1+=b,
            s+=u
        b=1
        for w in e[v][::-1]:
            b=b*dp1[w]*inv[sz1[w]]%M
            c2+=b,
        c[v]=c1,c2[::-1]
        sz1[v]=s
        dp1[v]=b*fac[s-1]%M
    # print(dp1)
    sz2[0]=1
    dp2[0]=1
    for v in o:
        l=len(e[v])
        c1,c2=c[v]
        uv=sz2[v]-1
        tv=dp2[v]*inv[uv]
        for i,w in enumerate(e[v]):
            tw=c1[i]*c2[i+1]%M
            uw=uv+sz1[v]-sz1[w]-1
            dp2[w]=tv*tw*fac[uw]%M
            sz2[w]=uw+2
    # print(dp2)
    a=[]
    for dp1,dp2,sz1,sz2 in zip(dp1,dp2,sz1,sz2):
        sz1-=1
        sz2-=1
        a+=str(dp1*dp2*inv[sz1]*inv[sz2]*fac[sz1+sz2]%M),
    print('\n'.join(a))
main()

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10**7)
M=10**9+7
N=10**6
fac=[0]*(N+1)
fac[0]=b=1
for i in range(1,N+1):fac[i]=b=b*i%M
inv=[0]*(N+1)
inv[N]=b=pow(fac[N],M-2,M)
for i in range(N,0,-1):inv[i-1]=b=b*i%M
def dfs1(v,p):
    s=1
    l=[]
    c1,c2=[1],[1]
    for w in e[v]:
        if w==p:continue
        l+=w,
        dfs1(w,v)
        u=sz1[w]
        c1+=c1[-1]*dp1[w]*inv[u]%M,
        s+=u
    for w in l[::-1]:
        c2+=c2[-1]*dp1[w]*inv[sz1[w]]%M,
    e[v]=l
    c[v]=c1,c2[::-1]
    sz1[v]=s
    dp1[v]=c1[-1]*fac[s-1]%M
n,*t=open(0).read().split()
n=int(n)
e=[[]for _ in range(n)]
for a,b in zip(*[map(int,t)]*2):
    e[a-1]+=b-1,
    e[b-1]+=a-1,
sz1,sz2=[0]*n,[0]*n
dp1,dp2=[0]*n,[0]*n
c=[[]for _ in range(n)]
dfs1(0,-1)
# print(dp1)
sz2[0]=1
dp2[0]=1
s=[0]
while s:
    v=s.pop()
    l=len(e[v])
    c1,c2=c[v]
    uv=sz2[v]-1
    tv=dp2[v]*inv[uv]
    for i,w in enumerate(e[v]):
        tw=c1[i]*c2[i+1]%M
        uw=uv+sz1[v]-sz1[w]-1
        dp2[w]=tv*tw*fac[uw]%M
        sz2[w]=uw+2
        s+=w,
# print(dp2)
for i in range(n):
    u1=sz1[i]-1
    u2=sz2[i]-1
    print(dp1[i]*dp2[i]*inv[u1]*inv[u2]*fac[u1+u2]%M)

Submission status: Accepted

Solution code:
# 全方位DP
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
from collections import defaultdict, deque
from math import factorial

MOD = 10**9+7
class Facts():
    def __init__(self, max_num=10**5, p=10**9 + 7):
        self.p = p
        self.max_num = max_num
        self.fact = [1] * (self.max_num + 1)
        for i in range(1, self.max_num + 1):
            self.fact[i] = self.fact[i-1] * i
            self.fact[i] %= self.p

    def power_func(self, a, b):
        ans = 1
        while b > 0:
            if b & 1:
                ans = ans * a % self.p
            a = a * a % self.p
            b >>= 1
        return ans

    def fact_inv(self, a):
        return self.power_func(a, self.p-2) % self.p

n = int(input())
fact = Facts(max_num=200000)
edges = defaultdict(lambda: [])

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

# step1 吸い上げ
size = [1 for _ in range(n+1)]
def dfs1(num, par=-1):
    res = 1
    for node in edges[num]:
        if node == par:
            continue
        else:
            res += dfs1(node, num)
    res %= MOD
    size[num] = res
    return res
dfs1(1)
# print(size)
dp = [0 for _ in range(n+1)]
def dfs2(n, par=-1):
    res = fact.fact[size[n] - 1]
    for node in edges[n]:
        if node == par:
            continue
        else:
            res *= dfs2(node, n) * fact.fact_inv(fact.fact[size[node]])
    res %= MOD
    dp[n] = res
    return res
dfs2(1)
# print(dp)

# step2 還元
ans = [0 for _ in range(n+1)]
inv_1 = fact.fact_inv(fact.fact[n-1])
def dfs3(num, par=-1):
    if par != -1:
        res = dp[num] * fact.fact_inv(fact.fact[size[num] - 1]) * \
            fact.fact[n-1] * ans[par] * inv_1 * \
            fact.fact[n-size[num]-1] * fact.fact[size[num]] * \
            fact.fact_inv(dp[num]) * \
            fact.fact_inv(fact.fact[n-size[num]]) % MOD
        ans[num] = res
    else:
        ans[num] = dp[num]
    for node in edges[num]:
        if node == par:
            continue
        dfs3(node, num)
dfs3(1)
print("\n".join(list(map(str, ans[1:]))))

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10**6)
from collections import deque
MOD = 1000000007

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

dp = [0] * (N + 1) # represent the # if i is the root (1)
tree_size = [0]*(N + 1)
ans = [0] * (N + 1)

n_inv = [1, 1]
n_j_mod = [1, 1]

for i in range(2, N+1):
    n_inv.append((pow(i, MOD-2, MOD) * n_inv[-1]) % MOD)
    n_j_mod.append((n_j_mod[-1] * i) % MOD)


def dfs(i, father=-1):
    method_num = 1
    t_size = 1
    for child in childs[i]:
        if child != father:
            num, size = dfs(child, i)
            method_num = (method_num * num * n_inv[size]) % MOD
            t_size += size
    method_num = (method_num * n_j_mod[t_size - 1]) % MOD
    dp[i] = method_num
    tree_size[i] = t_size
    return method_num, t_size

def rdfs(i, f_num, father=-1):
    ans[i] = (dp[i] * f_num * n_j_mod[N-1] * n_inv[N - tree_size[i]] * n_inv[tree_size[i] - 1]) % MOD

    for child in childs[i]:
        if child != father:
            cf_num = (ans[i] * n_j_mod[tree_size[child]] * n_j_mod[N - tree_size[child] - 1] * n_inv[N - 1] * pow(dp[child], MOD-2, MOD)) % MOD
            rdfs(child, cf_num, i)
dfs(1)

rdfs(1, 1)
print('\n'.join(list(map(str, ans[1:]))))

Submission status: Accepted

Solution code:
from fractions import gcd
import sys
sys.setrecursionlimit(4100000)

def os(): return input()
def oi(): return int(input())
def oli(): return map(int, input().split())
def olai(): return list(map(int, input().split()))
def olas(): return list(input().split())
def mlai(L): return [int(input()) for _ in range(L)]
def mlas(L): return [input() for _ in range(L)]
def ar(a, b, c=-1, d=-1, INIT=0):
    if(c==-1): return [[INIT]*b for _ in range(a)]
    if(d==-1): return [[[INIT]*c for _ in range(b)] for __ in range(a)]
    return [[[[INIT]*d for _ in range(c)] for __ in range(b)] for ___ in range(a)]

def lcm(a, b): return (a*b)//gcd(a, b)
#MOD
P = 10**9 + 7
N = 200001 #使う最大値+1以上にする、値に注意3*10^5とかにしとくと安心
inv = [0] + [1] # 1/x
finv = [1] + [1] # 1/x!
fac = [1] + [1] # x!
for i in range(2, N):
  inv += [inv[P % i] * (P - int(P / i)) % P]
  fac += [(fac[i-1] * i) % P]
  finv += [(finv[i-1] * inv[i]) % P]

def comb(a, b):
    if a<b or b < 0: return 0 # error
    return (fac[a] * ((finv[b] * finv[a-b]) % P)) %P

#全方位木dp
#-------------------------------------------------------------------
#扱うクラス
class T:
    num = 1
    child = 0

    def __init__(self, a, b):
        self.num = a
        self.child = b

#零元
zero = T(1, 0)
#一個上に遷移した時の変化
def step(x):
    return T(x.num, x.child+1)
#マージ
def merge(x, y):
    return T((x.num*y.num*comb(x.child+y.child, x.child))%P, x.child+y.child)

G = [[] for _ in range(200001)]
down_data = [zero for _ in range(200001)]
dat = [zero for _ in range(200001)]

def dfs(now, parent):
    cnt = 0
    for to in G[now]:
        if(to==parent): continue
        cnt += 1
        dfs(to, now)
        down_data[now] = merge(down_data[now], step(down_data[to]))

def dfs_rev(now, parent, rev):
    #累積
    left = []
    right = []
    cnt = 0
    for to in G[now]:
        if(to==parent): continue
        if(len(left)==0): left.append(step(down_data[to]))
        else: left.append(merge(left[cnt-1], step(down_data[to])))
        cnt += 1
    cnt = 0
    for to in reversed(G[now]):
        if(to==parent): continue
        if(len(right)==0): right.append(step(down_data[to]))
        else: right.append(merge(right[cnt-1], step(down_data[to])))
        cnt += 1
    cnt = 0
    dat[now] = merge(rev, down_data[now])

    for to in G[now]:
        if(to==parent): continue
        x = zero if cnt==0 else left[cnt-1]
        y = zero if cnt==len(right)-1 else right[len(right)-2-cnt]
        dfs_rev(to, now, step(merge(rev, merge(x, y))))
        cnt += 1
#-------------------------------------------------------------------
def main():
    n = oi()
    for i in range(n-1):
        a, b = oli()
        G[a].append(b)
        G[b].append(a)
    root = -1
    for i in range(1, n+1):
        if(len(G[i]) == 1):
            root = i
            break
    dfs(root, -1)
    dfs_rev(root, -1, zero)
    for i in range(1, n+1):
        print(dat[i].num)

if __name__ == "__main__": main()

Submission status: Accepted

Solution code:
from fractions import gcd
import sys
sys.setrecursionlimit(4100000)

def os(): return input()
def oi(): return int(input())
def oli(): return map(int, input().split())
def olai(): return list(map(int, input().split()))
def olas(): return list(input().split())
def mlai(L): return [int(input()) for _ in range(L)]
def mlas(L): return [input() for _ in range(L)]
def ar(a, b, c=-1, d=-1, INIT=0):
    if(c==-1): return [[INIT]*b for _ in range(a)]
    if(d==-1): return [[[INIT]*c for _ in range(b)] for __ in range(a)]
    return [[[[INIT]*d for _ in range(c)] for __ in range(b)] for ___ in range(a)]

def lcm(a, b): return (a*b)//gcd(a, b)
#MOD
P = 10**9 + 7
N = 200001 #使う最大値+1以上にする、値に注意3*10^5とかにしとくと安心
inv = [0] + [1] # 1/x
finv = [1] + [1] # 1/x!
fac = [1] + [1] # x!
for i in range(2, N):
  inv += [inv[P % i] * (P - int(P / i)) % P]
  fac += [(fac[i-1] * i) % P]
  finv += [(finv[i-1] * inv[i]) % P]

def comb(a, b):
    if a<b or b < 0: return 0 # error
    return (fac[a] * ((finv[b] * finv[a-b]) % P)) %P

#-------------------------------------------------------------------
#全方位木dpで扱うクラス
class T:
    num = 1
    child = 0

    def __init__(self, a, b):
        self.num = a
        self.child = b

#零元
zero = T(1, 0)
#一個遷移した時の変化
def step(x):
    return T(x.num, x.child+1)
#マージ
def merge(x, y):
    if(x.num==-1): return y
    if(y.num==-1): return x
    return T((x.num*y.num*comb(x.child+y.child, x.child))%P, x.child+y.child)

G = [[] for _ in range(200001)]
down_data = [zero for _ in range(200001)]
dat = [zero for _ in range(200001)]

def dfs(now, parent):
    cnt = 0
    for to in G[now]:
        if(to==parent): continue
        cnt += 1
        dfs(to, now)
        down_data[now] = merge(down_data[now], step(down_data[to]))

def dfs_rev(now, parent, rev):
    #累積
    left = []
    right = []
    cnt = 0
    for to in G[now]:
        if(to==parent): continue
        if(len(left)==0): left.append(step(down_data[to]))
        else: left.append(merge(left[cnt-1], step(down_data[to])))
        cnt += 1
    cnt = 0
    for to in reversed(G[now]):
        if(to==parent): continue
        if(len(right)==0): right.append(step(down_data[to]))
        else: right.append(merge(right[cnt-1], step(down_data[to])))
        cnt += 1
    cnt = 0
    dat[now] = merge(rev, down_data[now])

    for to in G[now]:
        if(to==parent): continue
        x = zero if cnt==0 else left[cnt-1]
        y = zero if cnt==len(right)-1 else right[len(right)-2-cnt]
        dfs_rev(to, now, step(merge(rev, merge(x, y))))
        cnt += 1
#-------------------------------------------------------------------
def main():
    n = oi()
    for i in range(n-1):
        a, b = oli()
        G[a].append(b)
        G[b].append(a)
    root = -1
    for i in range(1, n+1):
        if(len(G[i]) == 1):
            root = i
            break
    dfs(root, -1)
    dfs_rev(root, -1, zero)
    for i in range(1, n+1):
        print(dat[i].num)

if __name__ == "__main__": main()

Submission status: Accepted

Solution code:
from fractions import gcd
import sys
sys.setrecursionlimit(4100000)

def os(): return input()
def oi(): return int(input())
def oli(): return map(int, input().split())
def olai(): return list(map(int, input().split()))
def olas(): return list(input().split())
def mlai(L): return [int(input()) for _ in range(L)]
def mlas(L): return [input() for _ in range(L)]

def ar(a, b, c=-1, d=-1, INIT=0):
    if(c==-1): return [[INIT]*b for _ in range(a)]
    if(d==-1): return [[[INIT]*c for _ in range(b)] for __ in range(a)]
    return [[[[INIT]*d for _ in range(c)] for __ in range(b)] for ___ in range(a)]

def lcm(a, b): return (a*b)//gcd(a, b)

#MOD
P = 10**9 + 7
N = 200001 #使う最大値+1以上にする、値に注意3*10^5とかにしとくと安心
inv = [0] + [1] # 1/x
finv = [1] + [1] # 1/x!
fac = [1] + [1] # x!
for i in range(2, N):
  inv += [inv[P % i] * (P - int(P / i)) % P]
  fac += [(fac[i-1] * i) % P]
  finv += [(finv[i-1] * inv[i]) % P]

def comb(a, b):
    if a<b or b < 0: return 0 # error
    return (fac[a] * ((finv[b] * finv[a-b]) % P)) %P




class T:
    num = 1
    child = 0

    def __init__(self, a, b):
        self.num = a
        self.child = b

def step(x):
    return T(x.num, x.child+1)
def merge(x, y):
    if(x.num==-1): return y
    if(y.num==-1): return x
    return T((x.num*y.num*comb(x.child+y.child, x.child))%P, x.child+y.child)

G = [[] for _ in range(200001)]
down_data = [T(-1, -1) for _ in range(200001)]
dat = [T(-1, -1) for _ in range(200001)]

def dfs(now, parent):
    cnt = 0
    for to in G[now]:
        if(to==parent): continue
        cnt += 1
        dfs(to, now)
        down_data[now] = merge(down_data[now], step(down_data[to]))
    if(cnt==0): down_data[now] = T(1, 0)

def dfs_rev(now, parent, rev):
    left = []
    right = []
    cnt = 0
    for to in G[now]:
        if(to==parent): continue
        if(len(left)==0): left.append(step(down_data[to]))
        else: left.append(merge(left[cnt-1], step(down_data[to])))
        cnt += 1
    cnt = 0
    for to in reversed(G[now]):
        if(to==parent): continue
        if(len(right)==0): right.append(step(down_data[to]))
        else: right.append(merge(right[cnt-1], step(down_data[to])))
        cnt += 1
    cnt = 0
    dat[now] = merge(rev, down_data[now])
    for to in G[now]:
        if(to==parent): continue
        x = T(-1, -1) if cnt==0 else left[cnt-1]
        y = T(-1, -1) if cnt==len(right)-1 else right[len(right)-2-cnt]
        dfs_rev(to, now, step(merge(rev, merge(x, y))))
        cnt += 1

def main():
    n = oi()
    for i in range(n-1):
        a, b = oli()
        G[a].append(b)
        G[b].append(a)
    root = -1
    for i in range(1, n+1):
        if(len(G[i]) == 1):
            root = i
            break
    dfs(root, -1)
    dfs_rev(root, -1, T(1, 0))
    for i in range(1, n+1):
        print(dat[i].num)

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)

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

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]*fact[size[v]-1]%mod
    dpLeaf[pr] = dpLeaf[pr]*dpLeaf[v]*fact_inv[size[v]]%mod

ans = [0]*(N+1)
ans[1] = dpLeaf[1]
for v in order[1:]:
    pr = parent[v]
    ans[v] = (ans[pr]*pow(N-size[v], mod-2, mod)*size[v])%mod
print(*ans[1:], sep="\n")

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
import bisect
import heapq
import math
import random
import sys
import resource
from collections import Counter, defaultdict, deque
from decimal import ROUND_CEILING, ROUND_HALF_UP, Decimal
from functools import lru_cache, reduce
from itertools import combinations, combinations_with_replacement, product, permutations
from operator import add, mul, sub


sys.setrecursionlimit(10**6)
input = sys.stdin.readline
INF = 2**62-1


def read_int():
    return int(input())


def read_int_n():
    return list(map(int, input().split()))


def read_float():
    return float(input())


def read_float_n():
    return list(map(float, input().split()))


def read_str():
    return input().strip()


def read_str_n():
    return list(map(str, input().split()))


def error_print(*args):
    print(*args, file=sys.stderr)


def mt(f):
    import time

    def wrap(*args, **kwargs):
        s = time.time()
        ret = f(*args, **kwargs)
        e = time.time()

        error_print(e - s, 'sec')
        return ret

    return wrap


class Mod:
    def __init__(self, m):
        self.m = m

    def add(self, a, b):
        return (a + b) % self.m

    def sub(self, a, b):
        return (a - b) % self.m

    def mul(self, a, b):
        return ((a % self.m) * (b % self.m)) % self.m

    def div(self, a, b):
        return self.mul(a, pow(b, self.m-2, self.m))

    def pow(self, a, b):
        return pow(a, b, self.m)



M = Mod(10**9 + 7)
m = 10**9 + 7
fact = [1] * (2 * (10**5) + 1)
fact_inv = [0] * (2 * (10**5) + 1)
for i in range(1, 2 * (10**5)+1):
    fact[i] = M.mul(fact[i-1], i)
    fact_inv[i] = pow(fact[i], m-2, m)


@mt
def slv(N, AB):
    g = defaultdict(list)
    for a, b in AB:
        g[a].append(b)
        g[b].append(a)

    memo = defaultdict(dict)

    def f(u, p, flag=False):
        if u in memo and p in memo[u]:
            return memo[u][p]
        r = 1
        n = 1
        if p == 0 or flag:
            for v in g[u]:
                if v == p:
                    continue
                n_, r_ = f(v, u, flag)
                n += n_
                r = M.mul(r, r_)
                r = M.mul(r, fact_inv[n_])
            r = M.mul(r, fact[n-1])
        else:
            np, rp = f(p, u, False)
            na, ra = f(u, 0, False)
            r = M.div(ra, rp)
            r = M.mul(r, fact[np])
            n = na - np
            r = M.mul(r, fact_inv[na-1])
            r = M.mul(r, fact[n-1])

        memo[u][p] = n, r
        return n, r

    f(1, 0, True)

    for i in range(1, N+1):
        print(f(i, 0, False)[1])


def main():
    N = read_int()
    AB = [read_int_n() for _ in range(N-1)]
    slv(N, AB)

    # N = (10**5) * 2
    # AB = [(_, _+1) for _ in range(N-1)]
    # (slv(N, AB))


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
import bisect
import heapq
import math
import random
import sys
import resource
from collections import Counter, defaultdict, deque
from decimal import ROUND_CEILING, ROUND_HALF_UP, Decimal
from functools import lru_cache, reduce
from itertools import combinations, combinations_with_replacement, product, permutations
from operator import add, mul, sub


sys.setrecursionlimit(10**6)
input = sys.stdin.readline
INF = 2**62-1


def read_int():
    return int(input())


def read_int_n():
    return list(map(int, input().split()))


def read_float():
    return float(input())


def read_float_n():
    return list(map(float, input().split()))


def read_str():
    return input().strip()


def read_str_n():
    return list(map(str, input().split()))


def error_print(*args):
    print(*args, file=sys.stderr)


def mt(f):
    import time

    def wrap(*args, **kwargs):
        s = time.time()
        ret = f(*args, **kwargs)
        e = time.time()

        error_print(e - s, 'sec')
        return ret

    return wrap


class Mod:
    def __init__(self, m):
        self.m = m

    def add(self, a, b):
        return (a + b) % self.m

    def sub(self, a, b):
        return (a - b) % self.m

    def mul(self, a, b):
        return (a * b) % self.m

    def div(self, a, b):
        return self.mul(a, self.pow(b, self.m-2))

    @lru_cache(maxsize=None)
    def pow(self, a, b):
        return pow(a, b, self.m)


M = Mod(10**9 + 7)
m = 10**9 + 7
fact = [1] * (2 * (10**5) + 1)
fact_inv = [0] * (2 * (10**5) + 1)
for i in range(1, 2 * (10**5)+1):
    fact[i] = M.mul(fact[i-1], i)
    fact_inv[i] = pow(fact[i], m-2, m)


@mt
def slv(N, AB):
    g = defaultdict(list)
    for a, b in AB:
        g[a].append(b)
        g[b].append(a)

    memo = defaultdict(dict)

    def f(u, p, flag=False):
        if u in memo and p in memo[u]:
            return memo[u][p]
        r = 1
        n = 1
        if p == 0 or flag:
            for v in g[u]:
                if v == p:
                    continue
                n_, r_ = f(v, u, flag)
                n += n_
                r = M.mul(r, r_)
                r = M.mul(r, fact_inv[n_])
            r = M.mul(r, fact[n-1])
        else:
            np, rp = f(p, u, False)
            na, ra = f(u, 0, False)
            r = M.div(ra, rp)
            r = M.mul(r, fact[np])
            n = na - np
            r = M.mul(r, fact_inv[na-1])
            r = M.mul(r, fact[n-1])

        memo[u][p] = n, r
        return n, r

    f(1, 0, True)

    for i in range(1, N+1):
        print(f(i, 0, False)[1])


def main():
    N = read_int()
    AB = [read_int_n() for _ in range(N-1)]
    slv(N, AB)

    # N = (10**5) * 2
    # AB = [(_, _+1) for _ in range(N-1)]
    # (slv(N, AB))


if __name__ == '__main__':
    main()