Cod sursa(job #24719)

Utilizator vladcyb1Vlad Berteanu vladcyb1 Data 3 martie 2007 13:40:38
Problema Secventa 5 Scor 70
Compilator fpc Status done
Runda Arhiva de probleme Marime 2.72 kb

  const
       FIN = 'secv5.in';
       FOUT = 'secv5.out';
       NMAX = 1 SHL 20; // vezi sa pui 20
       PRIM = 666013;


 type
      int = array[ 1..NMAX ] of longint;
      type hash_data = ^cell;
       cell = record inf : qword;
                     cod : longint;
                     urm : hash_data;
                     end;


 var
      A, V1, V2 : int;
      H : array[ 0..PRIM ] of hash_data;
      f, g : text;
      N, L, U : longint;
      ans : qword;

   function find( X : qword ) : longint; inline; // returneaza cheia sau 0 in caz ca nu gaseste
   var tmp : hash_data;
    begin
     tmp := H[ X mod PRIM ];
      while tmp <> nil do
        begin
          if tmp^.inf = X then begin find := tmp^.cod; exit; end;
          tmp := tmp^.urm;
         end;
      find := 0;
    end;

  procedure add( inf : qword; cod : longint ); inline;
   var p : hash_data;
       key : longint;
    begin
      key :=  inf mod PRIM;
      new( p ); p^.inf := inf; p^.cod := cod; p^.urm := H[key]; H[key] := p;
    end;


  procedure read_data; inline;
   var s : string;
       i, cod, K : longint;
       x : qword;
   begin
    assign( f, FIN ); reset( f ); readln( f, N, L, U );
    K := 0;
     for i := 1 to N do
       begin
        readln( f, s );
        val( s, x, cod );
        A[i] := find( X );
        if A[i] = 0 then begin inc( K ); A[i] := K; add( X, k ); end;
       end;
    close( f );
   end;

  procedure compute( L, U : longint ); inline;
   var i, j, PL, PU, NRL, NRU : longint;
   begin
     // nr de elemente distincte la un moment dat
    if L = 0 then begin PL := 2; NRL := 0; end
             else begin PL := 1; V1[ A[1] ] := 1; NRL := 1; end;
    if U = 0 then begin PU := 2; NRU := 0; end
             else begin PU := 1; V2[ A[1] ] := 1; NRU := 1; end;
   ans := PL - PU;

    for  i := 2 to N do
      begin
        inc( V1[A[i]] ); if V1[A[i]] = 1 then inc( NRL );
        inc( V2[A[i]] ); if V2[A[i]] = 1 then inc( NRU );
        if NRL > L then
             for j := PL to i do
                begin
                  dec( V1[ A[j] ] );
                  if V1[A[j]] = 0 then begin dec( NRL ); PL := j + 1; break; end;
                 end;
       if NRU > U then
            for j := PU to i do
               begin
                 dec( V2[A[j]] );
                 if V2[A[j]] = 0 then begin dec( NRU ); PU := j + 1; break; end;
                end;
        ans := ans + int64( PL - PU );
       end;
      end;

    procedure save; inline;
     begin
      assign( g, FOUT ); rewrite( g );
      writeln( g, ans ); close( g );
     end;

    begin
     read_data;
     ans := 0;
     compute( L - 1, U );
     save;
    end.