結果
問題 | No.2337 Equidistant |
ユーザー | とりゐ |
提出日時 | 2023-06-02 22:09:23 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 2,913 ms / 4,000 ms |
コード長 | 4,018 bytes |
コンパイル時間 | 306 ms |
コンパイル使用メモリ | 82,788 KB |
実行使用メモリ | 242,368 KB |
最終ジャッジ日時 | 2024-06-08 23:20:54 |
合計ジャッジ時間 | 36,252 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 49 ms
54,912 KB |
testcase_01 | AC | 45 ms
54,912 KB |
testcase_02 | AC | 49 ms
55,040 KB |
testcase_03 | AC | 44 ms
54,912 KB |
testcase_04 | AC | 44 ms
54,912 KB |
testcase_05 | AC | 48 ms
54,912 KB |
testcase_06 | AC | 197 ms
79,948 KB |
testcase_07 | AC | 211 ms
80,324 KB |
testcase_08 | AC | 181 ms
79,456 KB |
testcase_09 | AC | 191 ms
79,548 KB |
testcase_10 | AC | 194 ms
79,492 KB |
testcase_11 | AC | 1,674 ms
193,964 KB |
testcase_12 | AC | 1,663 ms
193,548 KB |
testcase_13 | AC | 1,656 ms
191,124 KB |
testcase_14 | AC | 1,686 ms
192,116 KB |
testcase_15 | AC | 1,655 ms
194,140 KB |
testcase_16 | AC | 1,790 ms
193,528 KB |
testcase_17 | AC | 1,719 ms
193,788 KB |
testcase_18 | AC | 1,780 ms
193,572 KB |
testcase_19 | AC | 1,762 ms
192,680 KB |
testcase_20 | AC | 1,772 ms
193,552 KB |
testcase_21 | AC | 1,726 ms
187,696 KB |
testcase_22 | AC | 1,128 ms
242,368 KB |
testcase_23 | AC | 1,443 ms
197,052 KB |
testcase_24 | AC | 2,440 ms
189,144 KB |
testcase_25 | AC | 1,483 ms
197,704 KB |
testcase_26 | AC | 2,913 ms
197,556 KB |
testcase_27 | AC | 1,671 ms
214,200 KB |
testcase_28 | AC | 1,602 ms
210,272 KB |
ソースコード
class JumpOnTree: def __init__(self, edges, root=0): self.n = len(edges) self.edges = edges self.root = root self.logn = (self.n - 1).bit_length() self.depth = [-1] * self.n self.depth[self.root] = 0 self.parent = [[-1] * self.n for _ in range(self.logn)] self.dfs() self.doubling() def dfs(self): stack = [self.root] while stack: u = stack.pop() for v in self.edges[u]: if self.depth[v] == -1: self.depth[v] = self.depth[u] + 1 self.parent[0][v] = u stack.append(v) def doubling(self): for i in range(1, self.logn): for u in range(self.n): p = self.parent[i - 1][u] if p != -1: self.parent[i][u] = self.parent[i - 1][p] def lca(self, u, v): du = self.depth[u] dv = self.depth[v] if du > dv: du, dv = dv, du u, v = v, u d = dv - du i = 0 while d > 0: if d & 1: v = self.parent[i][v] d >>= 1 i += 1 if u == v: return u logn = (du - 1).bit_length() for i in range(logn - 1, -1, -1): pu = self.parent[i][u] pv = self.parent[i][v] if pu != pv: u = pu v = pv return self.parent[0][u] def dist(self,u,v): L=self.lca(u,v) return self.depth[u]+self.depth[v]-self.depth[L]*2 def jump(self, u, v, k): if k == 0: return u p = self.lca(u, v) d1 = self.depth[u] - self.depth[p] d2 = self.depth[v] - self.depth[p] if d1 + d2 < k: return -1 if k <= d1: d = k else: u = v d = d1 + d2 - k i = 0 while d > 0: if d & 1: u = self.parent[i][u] d >>= 1 i += 1 return u from sys import stdin input=lambda :stdin.readline()[:-1] n,q=map(int,input().split()) edge=[[] for i in range(n)] for i in range(n-1): a,b=map(lambda x:int(x)-1,input().split()) edge[a].append(b) edge[b].append(a) JT=JumpOnTree(edge) query=[[] for i in range(n)] for i in range(q): s,t=map(lambda x:int(x)-1,input().split()) d=JT.dist(s,t) if d%2: continue mid=JT.jump(s,t,d//2) ng1=JT.jump(mid,s,1) ng2=JT.jump(mid,t,1) query[mid].append((i,ng1,ng2)) def rerooting(query): dp=[[E]*len(edge[v]) for v in range(n)] # dfs1 memo=[E]*n for v in order[::-1]: res=E for i in range(len(edge[v])): if edge[v][i]==par[v]: continue dp[v][i]=memo[edge[v][i]] res=merge(res,f(dp[v][i],edge[v][i])) memo[v]=g(res,v) # dfs2 memo2=[E]*n for v in order: for i in range(len(edge[v])): if edge[v][i]==par[v]: dp[v][i]=memo2[v] s=len(edge[v]) cumR=[E]*(s+1) cumR[s]=E for i in range(s,0,-1): cumR[i-1]=merge(cumR[i],f(dp[v][i-1],edge[v][i-1])) cumL=E for i in range(s): if edge[v][i]!=par[v]: val=merge(cumL,cumR[i+1]) memo2[edge[v][i]]=g(val,v) cumL=merge(cumL,f(dp[v][i],edge[v][i])) ans=[0]*q for v in range(n): if query[v]: dic={} for i in range(len(edge[v])): dic[edge[v][i]]=dp[v][i] for i,ng1,ng2 in query[v]: res=n res-=dic[ng1] res-=dic[ng2] ans[i]=res return ans E=0 def f(res,v): return res def g(res,v): return res+1 def merge(a,b): return a+b def calc_ans(res,v): return g(res,v) # make order table # root = 0 from collections import deque order=[] par=[-1]*n todo=deque([0]) while todo: v=todo.popleft() order.append(v) for u in edge[v]: if u!=par[v]: par[u]=v todo.append(u) ans=rerooting(query) print(*ans,sep='\n')