結果

問題 No.898 tri-βutree
ユーザー terasaterasa
提出日時 2022-05-31 10:55:18
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 1,164 ms / 4,000 ms
コード長 2,651 bytes
コンパイル時間 176 ms
コンパイル使用メモリ 81,816 KB
実行使用メモリ 206,788 KB
最終ジャッジ日時 2023-10-21 00:34:22
合計ジャッジ時間 23,601 ms
ジャッジサーバーID
(参考情報)
judge14 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 727 ms
206,788 KB
testcase_01 AC 45 ms
55,848 KB
testcase_02 AC 55 ms
63,632 KB
testcase_03 AC 55 ms
63,620 KB
testcase_04 AC 55 ms
63,620 KB
testcase_05 AC 54 ms
63,616 KB
testcase_06 AC 54 ms
63,620 KB
testcase_07 AC 1,147 ms
114,804 KB
testcase_08 AC 1,109 ms
115,276 KB
testcase_09 AC 1,150 ms
115,096 KB
testcase_10 AC 1,117 ms
115,244 KB
testcase_11 AC 1,145 ms
115,284 KB
testcase_12 AC 1,164 ms
114,804 KB
testcase_13 AC 1,125 ms
115,260 KB
testcase_14 AC 1,114 ms
115,652 KB
testcase_15 AC 1,097 ms
114,976 KB
testcase_16 AC 1,104 ms
115,424 KB
testcase_17 AC 1,120 ms
115,804 KB
testcase_18 AC 1,098 ms
114,836 KB
testcase_19 AC 1,094 ms
115,664 KB
testcase_20 AC 1,111 ms
115,200 KB
testcase_21 AC 1,118 ms
115,208 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys
import pypyjit
import itertools
import heapq
import math
from collections import deque, defaultdict
import bisect

input = sys.stdin.readline
sys.setrecursionlimit(10 ** 6)
pypyjit.set_param('max_unroll_recursion=-1')


def index_lt(a, x):
    'return largest index s.t. A[i] < x or -1 if it does not exist'
    return bisect.bisect_left(a, x) - 1


def index_le(a, x):
    'return largest index s.t. A[i] <= x or -1 if it does not exist'
    return bisect.bisect_right(a, x) - 1


def index_gt(a, x):
    'return smallest index s.t. A[i] > x or len(a) if it does not exist'
    return bisect.bisect_right(a, x)


def index_ge(a, x):
    'return smallest index s.t. A[i] >= x or len(a) if it does not exist'
    return bisect.bisect_left(a, x)


class LCA:
    def __init__(self, N, E, root=0):
        self.N = N
        self.E = E
        self.K = N.bit_length()
        self.par = [[-1 for _ in range(N)] for _ in range(self.K)]
        self.depth = [None] * N

        self.order = [None] * N
        self._cnt = 0

        self.cost = [0] * N

        self.dfs(root, 0, -1)
        for k in range(self.K - 1):
            for i in range(self.N):
                if self.par[k][i] < 0:
                    continue
                self.par[k + 1][i] = self.par[k][self.par[k][i]]

    def dfs(self, v, d, p):
        self.par[0][v] = p
        self.depth[v] = d
        self.order[v] = self._cnt
        self._cnt += 1

        for c, dest in self.E[v]:
            if dest == p:
                continue
            self.cost[dest] = self.cost[v] + c
            self.dfs(dest, d + 1, v)

    def lca(self, u, v):
        if self.depth[u] > self.depth[v]:
            u, v = v, u
        d = self.depth[v] - self.depth[u]
        for k in range(self.K):
            if d & (1 << k):
                v = self.par[k][v]

        if u == v:
            return u
        for k in range(self.K)[::-1]:
            if self.par[k][u] != self.par[k][v]:
                u = self.par[k][u]
                v = self.par[k][v]
        return self.par[0][v]

    def dist(self, u, v):
        return self.cost[u] + self.cost[v] - 2 * self.cost[self.lca(u, v)]


N = int(input())
E = [[] for _ in range(N)]
for _ in range(N - 1):
    u, v, w = map(int, input().split())
    E[u].append((w, v))
    E[v].append((w, u))
solver = LCA(N, E)

Q = int(input())
for _ in range(Q):
    x, y, z = map(int, input().split())
    xo, yo, zo = solver.order[x], solver.order[y], solver.order[z]
    x, y, z = map(lambda x: x[0], sorted([(x, xo), (y, yo), (z, zo)], key=lambda x: x[1]))
    print((solver.dist(x, y) + solver.dist(y, z) + solver.dist(z, x)) // 2)
0