Cod sursa(job #24711)

Utilizator vladcyb1Vlad Berteanu vladcyb1 Data 3 martie 2007 13:21:52
Problema Secventa 5 Scor 0
Compilator fpc Status done
Runda Arhiva de probleme Marime 2.52 kb

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


  type hash_data = ^cell;
       cell = record inf, cod : longint;
                     urm : hash_data;
                     end;

      int = array[ 1..NMAX ] of longint;

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


  function find( X : longint ) : longint; // 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, cod : longint );
   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;
   var s : string;
       i, x, cod, K : longint;
   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( var P : int; L : longint );
   var i, j, nr : longint;
   begin
    fillchar( V, sizeof( V ), 0 );
   // P[i] = lungimea maxima a secventei care se termina in i
   //          si are cel mult L elem distincte
    NR := 0; // nr de elemente distincte la un moment dat
    if L = 0 then begin P[1] := 2; NR := 0; end
             else begin
                    P[1] := 1; V[ A[1] ] := 1; NR := 1;
                  end;
    for  i := 2 to N do
      begin
        P[i] := P[i-1];
        inc( V[A[i]] );
        if V[A[i]] = 1 then inc( NR );
        if NR > L then
             for j := P[ i - 1 ] to i do
                begin
                  dec( V[ A[j] ] );
                  if V[A[j]] = 0 then begin dec( NR ); P[i] := j + 1; break; end;
                 end;
      end;
   end;

   procedure solve;
    var i : longint;
    begin
      compute( V1, L - 1 );
      compute( V2, U );
      for i := 1 to N do ans := ans + V1[i] - V2[i];
    end;

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

    begin
     read_data;
     solve;
     save;
    end.