結果

問題 No.2949 Product on Tree
ユーザー shimon
提出日時 2024-11-04 10:30:04
言語 PyPy3
(7.3.15)
結果
TLE  
実行時間 -
コード長 3,816 bytes
コンパイル時間 367 ms
コンパイル使用メモリ 82,240 KB
実行使用メモリ 287,188 KB
最終ジャッジ日時 2024-11-04 10:30:34
合計ジャッジ時間 24,189 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other TLE * 9 -- * 37
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

import pypyjit
import sys
pypyjit.set_param('max_unroll_recursion=-1')
sys.setrecursionlimit(2000000)
class Rerooting:
"""
Rerooting
based on: https://algo-logic.info/tree-dp
Attributes:
G: List[List[Edge]]:
dp: List[List[DP]]: dp[v][i]: viDP
ans: List[DP]: ans[v]: v
Methods:
add_edge(a, b): ab
build(): DP
dfs(v, p): DP
bfs(v, dp_p, p): DP
Parameters:
N: int:
class DP: DP
identity: DP
class Edge:
merge(d1, d2): 2DP
add_root(d): DP
"""
# region
class DP: # DP
def __init__(self, dp_):
self.dp = dp_
identity = DP(0) # ( add_root(identity) )
class Edge:
def __init__(self, to):
self.to = to
def merge(self, d1: DP, d2: DP) -> DP:
return self.DP(d1.dp + d2.dp)
def add_root(self, d: DP, v: int) -> DP:
return self.DP((d.dp + 1) * C[v] % MOD)
# endregion
# region slv
def __init__(self, N: int):
self.G = [[] for _ in range(N)]
self.dp = [[] for _ in range(N)]
self.ans = [self.identity] * N
def add_edge(self, a: int, b: int):
self.G[a].append(self.Edge(b))
def build(self):
self.dfs(0) # DP
self.bfs(0, self.identity) # DP
def dfs(self, v: int, p: int = -1) -> DP: # v, p
dp_cum = self.identity
deg = len(self.G[v])
self.dp[v] = [self.identity] * deg
for i in range(deg):
u = self.G[v][i].to
if u == p:
continue
self.dp[v][i] = self.dfs(u, v)
dp_cum = self.merge(dp_cum, self.dp[v][i])
return self.add_root(dp_cum, v)
def bfs(self, v: int, dp_p: DP, p: int = -1): # bfs dfs
deg = len(self.G[v])
for i in range(deg): # bfsDP
if self.G[v][i].to == p:
self.dp[v][i] = dp_p
dp_l = [self.identity] * (deg + 1) # merge
dp_r = [self.identity] * (deg + 1) # merge
for i in range(deg):
dp_l[i + 1] = self.merge(dp_l[i], self.dp[v][i])
for i in range(deg - 1, -1, -1):
dp_r[i] = self.merge(dp_r[i + 1], self.dp[v][i])
self.ans[v] = self.add_root(dp_l[deg], v) # v
for i in range(deg): #
u = self.G[v][i].to
if u == p:
continue
self.bfs(u, self.add_root(self.merge(dp_l[i], dp_r[i + 1]), v), v)
# endregion
N = int(input())
C = list(map(int, input().split()))
MOD = 998244353
r = Rerooting(N)
for _ in range(N - 1):
u, v = map(int, input().split())
u -= 1
v -= 1
r.add_edge(u, v)
r.add_edge(v, u)
r.build()
A = r.ans
ans = 0
for a in A:
ans += a.dp
ans %= MOD
ans -= sum(C)
ans *= pow(2, MOD - 2, MOD)
ans %= MOD
print(ans)
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0