Pagini recente » Cod sursa (job #2945571) | Cod sursa (job #1042935) | Cod sursa (job #632255) | Cod sursa (job #2945582) | Cod sursa (job #760895)
Cod sursa(job #760895)
Program LCA_cu_RMQ;
type lista=^celula;
celula=record
v:longint;
next:lista;
end;
var graf:array [1..100000] of lista; {memorez graful cu liste de incidenta}
euler,nivel:array [1..1 shl 21] of longint; {nodurile din parcurgerea euler si nivelurile lor}
r:array [1..1 shl 21,0..22] of longint; {pentru RMQ}
apar,a:array [1..100000] of longint; {retin prima aparitie a nodului x in tabloul euler}
l:lista;
i,j,n,m,x,log,e,s,f,y,k:longint;
fi,fo:text;
function min(a,b:longint):longint;
begin
if nivel[a]<nivel[b] then min:=a else min:=b;
end;
procedure swap(var a,b:longint);
var aux:longint;
begin
aux:=a; a:=b; b:=aux;
end;
{Parcurgerea euler}
procedure dfs(nod,lev:longint);
var p:lista;
begin
p:=graf[nod];
inc(e);
nivel[e]:=lev;
euler[e]:=nod;
apar[nod]:=e;
while p<>nil do begin
if p<>nil then begin
dfs(p^.v,lev+1);
inc(e);
euler[e]:=nod;
nivel[e]:=lev;
end;
p:=p^.next;
end;
end;
{_____________________________}
begin
assign(fi,'lca.in');
assign(fo,'lca.out');
reset(fi); rewrite(fo); readln(fi,n,m);
for i:=2 to n do read(fi,a[i]); readln(fi);
for i:=n downto 2 do begin
new(l); l^.v:=i; l^.next:=graf[a[i]]; graf[a[i]]:=l;
end;
dfs(1,0);
for i:=1 to e do r[i,0]:=i;
log:=trunc(ln(e)/ln(2));
for j:=1 to log do
for i:=1 to e do
if i+(1 shl j)-1>e then break
else r[i,j]:=min(r[i,j-1],r[i+(1 shl (j-1)),j-1]);
for i:=1 to m do begin
readln(fi,x,y); if x>y then swap(x,y);
s:=apar[x]; f:=apar[y];
log:=trunc(ln(f-s+1)/ln(2));
k:=1 shl log;
writeln(fo,euler[min(r[s,log],r[f-k+1,log])]);
end;
close(fo);
end.