Cod sursa(job #31051)

Utilizator fogabFodor Gabor fogab Data 15 martie 2007 13:59:57
Problema Atac Scor 80
Compilator fpc Status done
Runda Arhiva de probleme Marime 3.8 kb
const inf=100001;
type pe=^e;
     e=record
       who,cost:longint;
       next:pe;
       end;
var f:text;
    n,m,i,j,x,y,miinv,k,x2,interv,miin,a1,b1,c1,d1,p,miinp:longint;
    c:array[0..18] of longint;
    a:array[1..32000] of pe;
    level,euler:array[1..64000] of word;
    father:array[1..32000] of word;
    fc:array[1..32000] of longint;
    min,minpos:array[1..64000,0..16] of word;
    poz:array[1..32000] of word;
    h:pe;

procedure go(s,l:word;var j:longint);
var me:pe;
    i:word;
begin
inc(j);
poz[s]:=j;
euler[j]:=s;
level[j]:=l;
me:=a[s]^.next;
if me=nil then
  else while me<>nil do
       begin
       go(me^.who,l+1,j);
       inc(j);
       euler[j]:=s;
       level[j]:=l;
       me:=me^.next;
       end;
end;

begin
assign(f,'atac.in');
reset(f);
read(f,n,m,p);
for i:=1 to n do begin
                 new(a[i]);
                 a[i]^.next:=nil;
                 end;
for i:=1 to n-1 do
  begin
    read(f,x,y);
    new(h);
    h^.who:=i+1;
    h^.cost:=y;
    h^.next:=a[x]^.next;
    a[x]^.next:=h;
    father[i+1]:=x;
    fc[i+1]:=y;
  end;
read(f,x,y,a1,b1,c1,d1);
close(f);
go(1,1,j);
j:=0;
c[0]:=1;
while c[j]<2*n do
  begin
    inc(j);
    c[j]:=c[j-1]*2;
  end;
k:=j-1;
for i:=1 to 2*n-1 do begin
                 min[i,0]:=level[i];
                 minpos[i,0]:=i;
                 end;
for j:=1 to k do
  for i:=1 to 2*n-1 do
    begin
      if (min[i,j-1]<min[i+c[j-1],j-1])
         or (min[i+c[j-1],j-1]=0) then
         begin
           min[i,j]:=min[i,j-1];
           minpos[i,j]:=minpos[i,j-1];
         end
    else begin
           min[i,j]:=min[i+c[j-1],j-1];
           minpos[i,j]:=minpos[i+c[j-1],j-1];
         end;
    end;

for i:=1 to m-p do
  begin
    if x=y then begin
    x:=(x*a1+y*b1) mod n+1;
    y:=(y*c1) mod n+1;
                end
    else begin
    k:=1;
    interv:=abs(poz[x]-poz[y])+1;
    while c[k]<interv do inc(k);
    if poz[x]>poz[y] then x2:=poz[y]
       else x2:=poz[x];
    miin:=min[x2,0];
    miinp:=minpos[x2,0];
    while interv<>0 do
      begin
        k:=0;
        while c[k]<=interv do inc(k);
        dec(k);
        if min[x2,k]<miin then
           begin
           miin:=min[x2,k];
           miinp:=minpos[x2,k];
           end;
        x2:=x2+c[k];
        interv:=interv-c[k];
      end;
    miinv:=inf;
    interv:=euler[miinp];
    x2:=x;
    while x2<>interv do
      begin
      if fc[x2]<miinv then miinv:=fc[x2];
      x2:=father[x2];
      end;
    x2:=y;
    while x2<>interv do
      begin
      if fc[x2]<miinv then miinv:=fc[x2];
      x2:=father[x2];
      end;
    x:=(x*a1+y*b1) mod n+1;
    y:=(y*c1+miinv*d1) mod n+1;
    end;
  end;
assign(f,'atac.out');
rewrite(f);
for i:=1 to p do
  begin
    if x=y then begin
    x:=(x*a1+y*b1) mod n+1;
    y:=(y*c1) mod n+1;
    writeln(f,0);
                end
    else begin
    k:=1;
    interv:=abs(poz[x]-poz[y])+1;
    while c[k]<interv do inc(k);
    if poz[x]>poz[y] then x2:=poz[y]
       else x2:=poz[x];
    miin:=min[x2,0];
    miinp:=minpos[x2,0];
    while interv<>0 do
      begin
        k:=0;
        while c[k]<=interv do inc(k);
        dec(k);
        if min[x2,k]<miin then
           begin
           miin:=min[x2,k];
           miinp:=minpos[x2,k];
           end;
        x2:=x2+c[k];
        interv:=interv-c[k];
      end;
    miinv:=inf;
    interv:=euler[miinp];
    x2:=x;
    while x2<>interv do
      begin
      if fc[x2]<miinv then miinv:=fc[x2];
      x2:=father[x2];
      end;
    x2:=y;
    while x2<>interv do
      begin
      if fc[x2]<miinv then miinv:=fc[x2];
      x2:=father[x2];
      end;
    x:=(x*a1+y*b1) mod n+1;
    y:=(y*c1+miinv*d1) mod n+1;
    writeln(f,miinv);
    end;
  end;
close(f);
end.