結果
| 問題 |
No.1817 Reversed Edges
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-01-21 23:26:22 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 439 ms / 2,000 ms |
| コード長 | 4,083 bytes |
| コンパイル時間 | 306 ms |
| コンパイル使用メモリ | 82,048 KB |
| 実行使用メモリ | 128,268 KB |
| 最終ジャッジ日時 | 2024-11-26 03:12:04 |
| 合計ジャッジ時間 | 8,204 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 23 |
ソースコード
class heavy_light_decomposition:
"The heavy edge oriented from the vertex `v` is the edge between `v` and `adj[vertex][0]`"
def __init__(self, N, adj, root=0):
self.N = N
self.adj = [row.copy() for row in adj]
self.root = root
self.sz = [1] * N
self.in_ = [0] * N
self.out = [0] * N
self.head = [0] * N
self.rev = [0] * N
self.par = [-1] * N
self._dfs_sz()
self._dfs_hld()
def _dfs_sz(self):
stack = []
stack.append(~self.root)
stack.append(self.root)
while stack:
v = stack.pop()
if v >= 0:
for nv in self.adj[v]:
if nv == self.par[v]:
continue
self.par[nv] = v
stack.append(~nv)
stack.append(nv)
else:
v = ~v
if v and self.adj[v][0] == self.par[v]:
self.adj[v][0], self.adj[v][-1] = self.adj[v][-1], self.adj[v][0]
for i, nv in enumerate(self.adj[v]):
if nv == self.par[v]:
continue
if self.sz[self.adj[v][0]] < self.sz[nv]:
self.adj[v][0], self.adj[v][i] = self.adj[v][i], self.adj[v][0]
self.sz[v] += self.sz[nv]
def _dfs_hld(self):
t = 0
self.head[self.root] = self.root
stack = []
stack.append(~self.root)
stack.append(self.root)
while stack:
v = stack.pop()
if v >= 0:
self.in_[v] = t
self.rev[t] = v
t += 1
for nv in reversed(self.adj[v]):
if nv == self.par[v]:
continue
self.head[nv] = self.head[v] if self.adj[v][0] == nv else nv
stack.append(~nv)
stack.append(nv)
else:
v = ~v
self.out[v] = t
def level_ancestor(self, v, level):
while True:
u = self.head[v]
if self.in_[v] - level >= self.in_[u]:
return self.rev[self.in_[v] - level]
level -= self.in_[v] - self.in_[u] + 1
v = self.par[u]
def lowest_common_ancestor(self, u, v):
while True:
if self.in_[u] > self.in_[v]:
u, v = v, u
if self.head[u] == self.head[v]:
return u
v = self.par[self.head[v]]
def query(self, u, v, e, q, f, edge=False):
l = e()
r = e()
while True:
if self.in_[u] > self.in_[v]:
u, v = v, u
l, r = r, l
if self.head[u] == self.head[v]:
break
l = f(q(self.in_[self.head[v]], self.in_[v] + 1), l)
v = self.par[self.head[v]]
return f(f(q(self.in_[u] + edge, self.in_[v] + 1), l), r)
def add(self, u, v, q, edge=False):
while True:
if self.in_[u] > self.in_[v]:
u, v = v, u
if self.head[u] == self.head[v]:
break
q(self.in_[self.head[v]], self.in_[v] + 1)
v = self.par[self.head[v]]
q(self.in_[u] + edge, self.in_[v] + 1)
def subtree(self, v, edge=False):
return (self.in_[v] + edge, self.out[v])
N = int(input())
edges = []
adj = [[] for _ in range(N)]
for _ in range(N - 1):
u, v = map(int, input().split())
u -= 1; v -= 1
edges.append((u, v))
adj[u].append(v)
adj[v].append(u)
hld = heavy_light_decomposition(N, adj)
imos = [0] * (N + 1)
for u, v in edges:
d = 1 if u < v else -1
if hld.in_[u] > hld.in_[v]:
u, v = v, u
d *= -1
l, r = hld.subtree(v)
imos[l] += d
imos[r] -= d
if d == -1:
imos[0] += 1
imos[-1] -= 1
for i in range(N):
imos[i + 1] += imos[i]
answer = [0] * N
for t in range(N):
answer[hld.rev[t]] = imos[t]
print(*answer, sep='\n')