Pagini recente » Cod sursa (job #1476156) | Cod sursa (job #586128) | Cod sursa (job #378780) | Cod sursa (job #1360274) | Cod sursa (job #2449227)
#!/usr/bin/env python3
import sys
sys.stdout = open('lca.out', 'w')
with open('lca.in', 'r') as f:
readInts = lambda: map(int, f.readline().split())
N, M = tuple(readInts())
N += 1
edges = [[] for _ in range(N)]
lvl = [-1] * N
euler = []
pos = [-1] * N
parent = list(readInts())
for i, p in enumerate(parent):
edges[p].append(i + 2)
crtNode, crtLvl = 1, 0
while True:
lvl[crtNode] = crtLvl
if pos[crtNode] < 0: pos[crtNode] = len(euler)
euler.append(crtNode)
if edges[crtNode]:
crtNode = edges[crtNode].pop()
crtLvl += 1
else:
if crtLvl == 0: break
crtLvl -= 1
crtNode = parent[crtNode - 2]
E, LOG = len(euler), 0
while 1 << (LOG + 1) < E: LOG += 1
RMQ = [[i] * (LOG + 1) for i in range(E)]
for j in range(1, LOG + 1):
for i in range(E):
jPow = 1 << (j - 1)
if i + jPow * 2 > E: break
RMQ[i][j] = RMQ[i][j - 1] if lvl[euler[RMQ[i][j-1]]] < lvl[euler[RMQ[i + jPow][j-1]]] else RMQ[i + jPow][j - 1]
def findMin(l, r):
l, r = min(l, r), max(l, r)
logDiff = 0
while 1 << (logDiff + 1) < r - l + 1: logDiff += 1
if lvl[euler[RMQ[l][logDiff]]] < lvl[euler[RMQ[r - (1 << logDiff) + 1][logDiff]]]:
return euler[RMQ[l][logDiff]]
else:
return euler[RMQ[r - (1 << logDiff) + 1][logDiff]]
for _ in range(M):
x, y = tuple(readInts())
print(findMin(pos[x], pos[y]))