Cod sursa(job #10309)

Utilizator bigsarpeadrian bigsarpe Data 28 ianuarie 2007 11:12:15
Problema Secventa 5 Scor 80
Compilator fpc Status done
Runda Arhiva de probleme Marime 1.92 kb
{$q-,r-,s-,d-,i-}
const maxn=1 shl 20;bucata=1 shl 16;modu=bucata-1;zero=ord('0');
var t:Text;
    V,A,B:array[0..maxn]of longword;
    by:array[0..maxn]of word;
    count:array[0..bucata]of longint;
    lg,loc,pas,i,n,la,lb:longint;s:string;
    last:longword;
    procedure init;
    begin
       assign(t,'secv5.in');reset(T);readln(t,n,la,lb);
       for i:=1 to N do
       begin
          readln(t,s);
          for pas:=1 to length(s) do v[i]:=V[i]*10+ord(s[pas])-zero;
       end;close(T);
    end;
    Procedure Radixsort;
    begin
       for i:=1 to N do begin by[i]:=V[i]and modu;inc(count[by[i]]);end;
       for i:=1 to bucata do inc(count[i],count[i-1]);
       for i:=N downto 1 do
       begin B[Count[By[i]]]:=i;dec(count[By[i]]);end;
       fillchar(count,sizeof(count),0);
       for i:=1 to N do begin by[i]:=V[i]shr 16;inc(count[by[i]]);end;
       for i:=1 to bucata do inc(count[i],count[i-1]);
       for i:=N downto 1 do
       begin A[Count[By[B[i]]]]:=B[i];dec(count[By[B[i]]]);end;
    end;
var return:int64;
   procedure get(limit:longint);
   begin
      i:=1;lg:=0;fillchar(a,sizeof(A),0);
      for pas:=1 to N do
      begin
         while (i<=N)and(lg<=limit)do
         begin if A[B[i]]=0 then inc(lg);inc(A[B[i]]);inc(i);end;
         if lg<=limit then inc(return,i) else inc(return,i-1);
         dec(A[B[pas]]);
         if A[B[pas]]=0 then dec(lg);
         if (lg<=limit)and (i>n) then break;
      end;
      inc(return,i*int64(n-pas));
   end;
{var t1:longint;t2:longint absolute $0:$046c;}
begin
{   t1:=t2;}
   init;
{   writeln((T2-t1)/18.2:0:6);}
   radixsort;
{   writeln((T2-t1)/18.2:0:6);}
   lg:=1;last:=V[a[1]];
   for i:=1 to N do if V[a[i]]=last then b[A[i]]:=lg else
   begin last:=V[A[i]];inc(lg);b[a[i]]:=lg;end;
   get(lb);return:=-return;get(la-1);
   assign(t,'secv5.out');rewrite(T);writeln(t,-return);close(T);
{   writeln((T2-t1)/18.2:0:6);}
end.