Cod sursa(job #86101)

Utilizator gurneySachelarie Bogdan gurney Data 23 septembrie 2007 14:56:32
Problema Curcubeu Scor 0
Compilator fpc Status done
Runda Autumn Warmup 2007, Runda 2 Marime 2.6 kb
program curcubeu;
  const
    fin='curcubeu.in';
    fout='curcubeu.out';
    nmax=1000005;
var
  cul,pas,f:array[1..nmax] of longint;
  next,prev:array[0..nmax] of longint;
  pred,last:array[0..nmax] of longint;
  cap,ult:longint;
  i,crt,n,a,b,c,x,ii:longint;

procedure switch(var x,y:longint);
  begin
    x:=x xor y;
    y:=x xor y;
    x:=x xor y;
  end;

label 10,20;

procedure insert(x,y:longint);
  begin
    pred[y]:=last[x];
    last[x]:=y;
  end;

begin
  assign(input,fin);
    reset(input);
    readln(n,a,b,c);
    if a>b then
      switch(a,b);
    cul[i]:=c;f[i]:=b;pas[1]:=1;
    insert(a,1);
    for i:=2 to n-1 do
      begin
        a:=(a*i)mod n;
        b:=(b*i) mod n;
        if a>b then
          switch(a,b);
        c:=(c*i) mod n;
        insert(a,i);
        cul[i]:=c;f[i]:=b;pas[i]:=i;
      end;
  close(input);
  assign(output,fout);
    rewrite(output);
    ult:=nmax;
    cap:=0;next[cap]:=ult;
    prev[ult]:=cap;
    for ii:=1 to n-1 do
      begin
        while last[ii]<>0 do
          begin
            i:=last[ii];
            x:=prev[ult];
            if next[cap]=ult then
              begin
                next[i]:=next[x];
                prev[next[x]]:=i;
                prev[i]:=x;
                next[x]:=i;
              end
            else
            while (x<>cap) do
              begin
                if (f[i]>=f[x])and(pas[i]<pas[x]) then
                  begin
                    next[i]:=next[x];
                    prev[next[x]]:=i;
                    prev[i]:=x;
                    next[x]:=i;
                  end
                else
                if (f[i]>=f[x])and(pas[i]>pas[x]) then
                  begin
                    next[prev[x]]:=next[x];
                    prev[next[x]]:=prev[x];
                    if prev[x]=cap then
                      begin
                        next[i]:=next[cap];
                        prev[next[cap]]:=i;
                        prev[i]:=cap;
                        next[cap]:=i;
                      end;
                  end
                else if (f[i]<=f[x]) and (pas[i]<pas[x]) then
                  goto 10;
                x:=prev[x];
              end;
            last[ii]:=pred[last[ii]];
          end;
        10:
        while ii>f[next[cap]] do
          begin
            if next[cap]<>ult then
              cap:=next[cap]
            else goto 20;
          end;
        20:
        if next[cap]=ult then
          writeln(0)
        else
          writeln(cul[next[cap]]);
      end;
  close(output);
end.