Cod sursa(job #760894)

Utilizator ctlin04UAIC.VlasCatalin ctlin04 Data 23 iunie 2012 14:07:08
Problema Lowest Common Ancestor Scor 0
Compilator fpc Status done
Runda Arhiva educationala Marime 2.05 kb
Program LCA_cu_RMQ;
 type lista=^celula;
        celula=record
               v:longint;
               next:lista;
               end;
var graf:array [1..100] of lista; {memorez graful cu liste de incidenta}
    euler,nivel:array [1..1 shl 10] of longint; {nodurile din parcurgerea euler si nivelurile lor}
    r:array [1..1 shl 10,0..22] of longint; {pentru RMQ}
    apar,a:array [1..100] 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.