Cod sursa(job #9910)

Utilizator andrei_infoMirestean Andrei andrei_info Data 27 ianuarie 2007 19:06:03
Problema Secventa 5 Scor 10
Compilator fpc Status done
Runda Arhiva de probleme Marime 2.78 kb
//infoarena secventa 5

type pnod = ^tnod;
     tnod = record
                nr : longword;
                frecv : longint;
                next : pnod;
                end;
     rr =record
        head,last:pnod;
        end;
const nmax = 1 shl 20;
      max = 1111111;

var n,l,u : longint;
    a:array[1..nmax] of longword;
    hash: array[1..2,0..max-1] of rr;
    rez : int64;

procedure citire;
var i:longint;
begin
assign(input,'secv5.in'); reset(input);
readln(n,l,u);
for i:=1 to n do readln(a[i]);
close(input);
end;

procedure addlist(x:longword; var r : rr);
var p:pnod;
begin
new(p); p^.nr:=x; p^.frecv:=1; p^.next:=nil;
if r.head = nil then r.head:=p
else r.last^.next:=p;
r.last:=p;
end;

function find(x:longword; hh : byte):longint;
var p:pnod;
    list:longint;
begin
list:=x mod max;
p:=hash[hh][list].head;
find:=0;

while p <> nil do
        begin
        if p^.nr = x then begin
                                find:=p^.frecv;
                                exit;
                                end;
        p:=p^.next;
        end;
end;

procedure update(x:longword; val : integer; hh:byte);
var p:pnod;
begin
if find(x,hh) = 0 then
        addlist(x,hash[hh][x mod max])
else
        begin
        p:=hash[hh][x mod max].head;
        while p<> nil do
                begin
                if p^.nr = x then
                        begin
                        p^.frecv:=p^.frecv+val;
                        exit;
                        end;
                p:=p^.next;
                end;
        end;
end;

function getfirst(poz,nrdis:longint; hh:byte):longint;
var i,nr:longint;
begin
i:=poz; nr:=0;
while (i < n) and (nr <nrdis) do
        begin
        inc(i);
        if find(a[i],hh) = 0 then inc(nr);
        update(a[i],1,hh);
        end;
if nr = 0 then begin getfirst:=1 shl 25; exit; end;
getfirst:=i;
if hh = 2 then
        begin
        i:=i+1;
        while (i <= n) and (find(a[i],hh)<>0) do
                begin
                updatE(a[i],1,hh);
                inc(i);
                end;
        getfirst:=i-1;
        end;
end;

procedure calc;
var start,stop1,stop2:longint;
begin
start:=1; stop1:=getfirst(0,l,1);
stop2:=getfirst(0,u,2);
rez:=stop2-stop1 +1;
while stop1 < n do
        begin
        inc(start); update(a[start-1],-1,1); update(a[start-1],-1,2);
        if find(a[start-1],1) = 0 then
                stop1:=getfirst(stop1,1,1);
        if find(a[start-1],2) = 0 then
                stop2:=getfirst(stop2,1,2);
        if (stop1 <= n) and (stop2 > n) then stop2:=n;
        if (stop1<= n) then
        rez:=rez+stop2-stop1+1;
        end;
assign(output,'secv5.out'); rewrite(output);
writeln(rez);
close(output);
end;

begin
citire;
calc;
end.