結果
| 問題 |
No.399 動的な領主
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-07-16 00:34:37 |
| 言語 | PyPy2 (7.3.15) |
| 結果 |
MLE
|
| 実行時間 | - |
| コード長 | 3,538 bytes |
| コンパイル時間 | 161 ms |
| コンパイル使用メモリ | 77,192 KB |
| 実行使用メモリ | 351,596 KB |
| 最終ジャッジ日時 | 2024-10-15 12:57:59 |
| 合計ジャッジ時間 | 10,912 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 17 MLE * 2 |
ソースコード
import sys
import math
sys.setrecursionlimit(10**6)
input = raw_input
range = xrange
def read_data():
N = int(input())
Es = [[] for i in range(N)]
for i in range(N - 1):
u, v = map(int, input().split())
u -= 1
v -= 1
Es[u].append(v)
Es[v].append(u)
Q = int(input())
moves = []
for i in range(Q):
a, b = map(int, input().split())
moves.append((a - 1, b - 1))
return N, Es, Q, moves
class Tree():
def __init__(self, N, Es, root):
self.n = N
self.root = root
self.child = [[] for i in range(N)]
self._set_child(Es)
def _set_child(self, Es):
que = [self.root]
visited = [False] * self.n
while que:
v = que.pop()
for u in Es[v]:
if visited[u]:
continue
self.child[v].append(u)
que.append(u)
visited[v] = True
class LCArmq():
def __init__(self, tree):
D, E, R = self._convert_to_RMQ(tree.child, tree.root, tree.n)
self._euler = E
self._reverse = R
self._RMQ = RMQ(D)
def _convert_to_RMQ(self, child, root, n):
''' LCA の前処理。 RMQ に置き換えるため、Euler tour で巡回して深さのリストをつくる。
'''
depth = []
euler = []
reverse = [0] * n
def euler_tour(node, d, depth, euler):
for v in child[node]:
euler.append(node)
depth.append(d)
euler_tour(v, d + 1, depth, euler)
euler.append(node)
depth.append(d)
euler_tour(root, 0, depth, euler)
for i, node in enumerate(euler):
reverse[node] = i
return depth, euler, reverse
def query(self, v, w):
i, j = self._reverse[v], self._reverse[w]
rmq = self._RMQ.query(i, j)
lca = self._euler[rmq]
return lca
class RMQ():
def __init__(self, A):
self._A = A
self._preprocess()
def _preprocess(self):
''' RMQ の前処理。
'''
n = len(self._A)
max_j = int(math.log(n, 2))
self._M = [list(range(n))]
for j in range(0, max_j):
shift = 1 << j
Mj = self._M[j]
Mjnext = []
for k1, k2 in zip(Mj, Mj[shift:]):
k = k1 if self._A[k1] < self._A[k2] else k2
Mjnext.append(k)
self._M.append(Mjnext)
def query(self, i, j):
if i == j: return i
if i > j: i, j = j, i
el = int(math.log(j - i, 2))
k1 = self._M[el][i]
k2 = self._M[el][j - (1 << el) + 1]
rmq = k1 if self._A[k1] < self._A[k2] else k2
return rmq
def solve(N, Es, Q, moves):
global imos1, imos2, imos3
tree = Tree(N, Es, 0)
lca_rmq = LCArmq(tree)
imos1 = [0] * N
imos2 = [0] * N
for a, b in moves:
v = lca_rmq.query(a, b)
imos1[a] += 1
imos1[b] += 1
imos1[v] -= 2
imos2[v] += 1
imos3 = [0] * N
dfs(0, tree.child)
return count_tax(imos3, imos2, N)
def dfs(u, child):
global imos3
ret = imos1[u]
for v in child[u]:
ret += dfs(v, child)
imos3[u] = ret
return ret
def count_tax(imos3, imos2, N):
tax = 0
for i in range(N):
t = imos3[i] + imos2[i]
tax += t * (t + 1)
return tax // 2
N, Es, Q, moves = read_data()
print(solve(N, Es, Q, moves))