結果

問題 No.2337 Equidistant
ユーザー FromBooskaFromBooska
提出日時 2023-06-03 11:02:07
言語 PyPy3
(7.3.15)
結果
MLE  
実行時間 -
コード長 3,938 bytes
コンパイル時間 954 ms
コンパイル使用メモリ 86,740 KB
実行使用メモリ 844,780 KB
最終ジャッジ日時 2023-08-28 07:42:35
合計ジャッジ時間 28,333 ms
ジャッジサーバーID
(参考情報)
judge11 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 93 ms
71,548 KB
testcase_01 AC 94 ms
71,724 KB
testcase_02 AC 92 ms
71,528 KB
testcase_03 AC 93 ms
71,528 KB
testcase_04 AC 92 ms
71,580 KB
testcase_05 AC 94 ms
71,628 KB
testcase_06 AC 236 ms
83,680 KB
testcase_07 AC 219 ms
83,632 KB
testcase_08 AC 222 ms
84,048 KB
testcase_09 AC 227 ms
84,232 KB
testcase_10 AC 221 ms
83,620 KB
testcase_11 AC 1,560 ms
141,500 KB
testcase_12 AC 1,517 ms
141,124 KB
testcase_13 AC 1,537 ms
143,080 KB
testcase_14 AC 1,564 ms
142,692 KB
testcase_15 AC 1,572 ms
142,876 KB
testcase_16 AC 1,535 ms
142,800 KB
testcase_17 AC 1,530 ms
140,576 KB
testcase_18 AC 1,573 ms
142,760 KB
testcase_19 AC 1,575 ms
143,176 KB
testcase_20 AC 1,656 ms
143,564 KB
testcase_21 AC 1,939 ms
312,108 KB
testcase_22 AC 1,188 ms
146,600 KB
testcase_23 AC 1,447 ms
145,984 KB
testcase_24 MLE -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

# 僕の持ってるLCAクラスではできないことをACの人はやっているのでそのLCAクラスをコピペさせてもらう
# https://yukicoder.me/submissions/877289

N, Q = map(int, input().split())
edges = [[] for i in range(N+1)]
for i in range(N-1):
    a, b = map(int, input().split())
    edges[a].append(b)
    edges[b].append(a)

## library of LCA by class
## index start from 0

import sys
sys.setrecursionlimit(10**7)
from collections import deque

class LCA:
    def __init__(self,n):
        self.size = n
        self.bitlen = n.bit_length()
        self.ancestor = [[0]*self.size for i in range(self.bitlen)]
        self.depth = [-1]*self.size
        self.dis = [-1]*self.size

    ## using [log_n][n] [n][log_n]
    ## [log_n][n] is tend to faster than [n][log_n]
    ## get parent by bfs is probably faster than dfs
    def make(self,root):
        self.depth[root] = 0
        self.dis[root] = 0
        q = deque([root])
        while q:
            now = q.popleft()
            for nex in edges[now]:
                if self.depth[nex]>= 0:
                    continue
                self.depth[nex] = self.depth[now]+1
                self.dis[nex] = self.dis[now]+1
                self.ancestor[0][nex] = now
                q.append(nex)
        for i in range(1,self.bitlen):
            for j in range(self.size):
                if self.ancestor[i-1][j] > 0:
                    self.ancestor[i][j] = self.ancestor[i-1][self.ancestor[i-1][j]]
    
    def lca(self,x,y):
        dx = self.depth[x]
        dy = self.depth[y]
        if dx < dy:
            x,y = y,x
            dx,dy = dy,dx
        dif = dx-dy
        while dif:
            s = dif & (-dif)
            x = self.ancestor[s.bit_length()-1][x]
            dif -= s
        while x != y:
            j = 0
            while self.ancestor[j][x] != self.ancestor[j][y]:
                j += 1
            if j == 0:
                return self.ancestor[0][x]
            x = self.ancestor[j-1][x]
            y = self.ancestor[j-1][y]
        return x

    def par(self,x,dep):
        now = x
        for i in range(self.bitlen)[::-1]:
            if 1 << i <= dep:
                now = self.ancestor[i][now]
                dep -= 1<<i
        return now


# 部分木、子の数をかぞえる、ここではルート1としている
import sys
sys.setrecursionlimit(10**7)

child = [0]*(N+1)
visited = [0]*(N+1)

def dfs(current):
    visited[current] = 1
    child[current] += 1
    
    for nxt in edges[current]:
        if visited[nxt] == 0:
            dfs(nxt)
            child[current] += child[nxt]
        
dfs(1)

#print(child)

# もらったLCAクラスを使ってみる

# もらったLCAクラスを使ってみる

lca = LCA(N+1) # 頂点数
lca.make(1) # ルート

for q in range(Q):
    s, t = map(int, input().split())

    if lca.depth[s] < lca.depth[t]:
        s, t = t, s
        # sの方を深い方にする
        # 同じ深さならそのまま

    p = lca.lca(s, t) # LCA, lowest common ancestor

    distance_st = lca.depth[s] + lca.depth[t] - lca.depth[p]*2
    
    if distance_st%2 == 1:
        print(0)
        continue
    
    center = lca.par(s, distance_st//2)
    # 深い方の頂点であるsから、距離の半分だけ木を登った点がcenter
    #print('center', center)

    if lca.depth[s] != lca.depth[t]:
        ans = child[center] - child[lca.par(s, distance_st//2-1)]
        # s, t の深さが違うときは
        # centerの子の数から、深い方sからcenterの一歩手前の頂点の子の数を引く
    else:
        #ans = N - child[lca.par(s, distance_st//2-1)] - child[lca.par(t,distance_st//2-1)]
        ans = N - child[lca.par(s, distance_st//2-1)] - child[lca.par(t, distance_st//2-1)]
        # s, tの深さが同じ時は
        # Nから
        # centerの一歩手前の頂点の子の数を引く、両方分

    print(ans)

0