結果

問題 No.898 tri-βutree
ユーザー terasaterasa
提出日時 2022-05-31 11:26:56
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 956 ms / 4,000 ms
コード長 2,655 bytes
コンパイル時間 209 ms
コンパイル使用メモリ 81,860 KB
実行使用メモリ 205,120 KB
最終ジャッジ日時 2023-10-21 00:36:12
合計ジャッジ時間 17,781 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 581 ms
205,120 KB
testcase_01 AC 46 ms
55,892 KB
testcase_02 AC 55 ms
63,676 KB
testcase_03 AC 53 ms
63,660 KB
testcase_04 AC 54 ms
63,660 KB
testcase_05 AC 53 ms
63,656 KB
testcase_06 AC 53 ms
63,660 KB
testcase_07 AC 919 ms
113,568 KB
testcase_08 AC 910 ms
113,652 KB
testcase_09 AC 920 ms
113,668 KB
testcase_10 AC 923 ms
113,648 KB
testcase_11 AC 906 ms
113,684 KB
testcase_12 AC 956 ms
113,552 KB
testcase_13 AC 909 ms
113,552 KB
testcase_14 AC 950 ms
113,656 KB
testcase_15 AC 932 ms
113,548 KB
testcase_16 AC 915 ms
113,660 KB
testcase_17 AC 916 ms
113,552 KB
testcase_18 AC 915 ms
113,744 KB
testcase_19 AC 897 ms
113,560 KB
testcase_20 AC 904 ms
113,672 KB
testcase_21 AC 905 ms
113,596 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