Cod sursa(job #1365898)

Utilizator ButnaruButnaru George Butnaru Data 28 februarie 2015 16:30:00
Problema Lowest Common Ancestor Scor 20
Compilator fpc Status done
Runda Arhiva educationala Marime 1.67 kb
//RMQ complexitate (NlogN+M);
program LCA;
type
fii=record
nr:byte;
f:array[0..30] of longint;
end;
datee=record
x,nod:longint;
end;
tabel=array[0..20,0..100001] of datee;
tabe=array[0..100001] of fii;
tabb=array[0..100001] of longint;
put2=array[0..18] of longint;
buf=array[0..1 shl 17] of char;
var
p2:put2; rmq:tabel;
ff1,ff2:buf;
t:tabe; pos,v:tabb;
n,m,i,j,nr,x,y:longint;
f1,f2:text;
procedure euler(lv,nod:longint);
var l:longint;
begin
nr:=nr+1; rmq[0,nr].x:=lv; rmq[0,nr].nod:=nod;
if pos[nod]=0 then pos[nod]:=nr;
for l:=1 to t[nod].nr do begin
euler(lv+1,t[nod].f[l]);
nr:=nr+1; rmq[0,nr].x:=lv; rmq[0,nr].nod:=nod;
end; end;
function min(a,b:datee):datee;
begin
if a.nod<b.nod then min:=a else min:=b; end;
procedure preprocesarermq;
var p:longint;
begin
p:=2; i:=1;
while 1+p div 2<=nr do begin
j:=1;
while j+p div 2<=nr do begin
rmq[i,j]:=min(rmq[i-1,j],rmq[i-1,j+p div 2]);
j:=j+1;
end;
i:=i+1; p:=p*2;
end;
p2[0]:=1;
for i:=1 to 18 do p2[i]:=p2[i-1]*2;
for i:=2 to n do v[i]:=v[i div 2]+1;
end;
function query(x,y:longint):longint;
var d,step,p,i:longint;
begin
if x>y then begin step:=x; x:=y; y:=step; end;
d:=(y-x+1); step:=v[d];
p:=p2[step];
if rmq[step,x].x<rmq[step,y-p+1].x then query:=rmq[step,x].nod else
query:=rmq[step,y-p+1].nod;
end;
begin
assign (f1,'lca.in');
assign (f2,'lca.out');
reset (f1);
rewrite (f2);
settextbuf(f1,ff1);
settextbuf(f2,ff2);
readln (f1,n,m);
for i:=1 to n-1 do begin
read (f1,x); t[x].nr:=t[x].nr+1;
t[x].f[t[x].nr]:=i+1;
end;
nr:=0; euler(0,1);
preprocesarermq;
for i:=1 to m do begin
readln (f1,x,y);
writeln (f2,query(pos[x],pos[y]));
end;
close (f1);
close (f2);
end.