Cod sursa(job #24712)

Utilizator vladcyb1Vlad Berteanu vladcyb1 Data 3 martie 2007 13:22:58
Problema Secventa 5 Scor 30
Compilator fpc Status done
Runda Arhiva de probleme Marime 2.49 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;

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


  function find( X : qword ) : longint; inline;
   var tmp, i : longint;
    begin
     tmp := X mod prim;
     for i := 1 to HC[tmp][0] do
       if HI[tmp][i] = X then begin find := HC[tmp][i]; exit; end;
      find := 0;
    end;

  procedure add( inf : qword; cod : longint ); inline;
   var  key : longint;
    begin
      key :=  inf mod PRIM;
      inc( HC[key][0] ); HC[key, HC[key][0] ] := cod;
                         HI[ key, HC[key][0] ] := inf;
    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, nr, 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;

    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.