結果

問題 No.399 動的な領主
ユーザー rpy3cpprpy3cpp
提出日時 2016-07-16 00:34:37
言語 PyPy2
(7.3.15)
結果
MLE  
実行時間 -
コード長 3,538 bytes
コンパイル時間 1,211 ms
コンパイル使用メモリ 77,220 KB
実行使用メモリ 368,260 KB
最終ジャッジ日時 2023-08-05 15:51:05
合計ジャッジ時間 13,440 ms
ジャッジサーバーID
(参考情報)
judge15 / judge13
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 71 ms
76,552 KB
testcase_01 AC 72 ms
76,556 KB
testcase_02 AC 86 ms
78,688 KB
testcase_03 AC 78 ms
78,616 KB
testcase_04 AC 119 ms
80,020 KB
testcase_05 AC 263 ms
101,096 KB
testcase_06 AC 886 ms
248,704 KB
testcase_07 AC 876 ms
253,932 KB
testcase_08 AC 777 ms
223,892 KB
testcase_09 AC 752 ms
226,836 KB
testcase_10 AC 135 ms
81,252 KB
testcase_11 AC 193 ms
90,336 KB
testcase_12 AC 575 ms
209,160 KB
testcase_13 AC 594 ms
229,780 KB
testcase_14 MLE -
testcase_15 MLE -
testcase_16 AC 762 ms
286,024 KB
testcase_17 AC 826 ms
230,880 KB
testcase_18 AC 803 ms
236,164 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

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))
0