Cod sursa(job #480017)

Utilizator zseeZabolai Zsolt zsee Data 26 august 2010 00:34:24
Problema Trie Scor 100
Compilator fpc Status done
Runda Arhiva educationala Marime 2.07 kb
program trie_;
const size__ = ord('z') - ord('a');

type 
     PTrie = ^TTrie;
     TTrie = record
               f : array['a'..'z'] of PTrie;
               n : word;
               nr : word;
              end; 
              
var fej : PTrie;

procedure Create( var x:PTrie );inline;
begin
 new(x);
 fillDword( x^.f, size__ , 0 );
 x^.n :=0;
 x^.nr :=0;
end;

procedure Add(const s:string );inline;
var l,i:byte;
    p:PTrie;
begin
 l := length(s);
 p := fej;
 i := 1;
 while i <= l do
  begin
   inc( p^.nr );
   if p^.f[s[i]]=nil then
          Create(p^.f[s[i]]);
   p := p^.f[s[i]];
   inc(i);
  end;
 inc(p^.n);
 inc(p^.nr);
end;

function getN(const s:string; var i:byte ):longword;inline;
var l:byte;
    p:PTrie;
begin
 l := length(s);
 i := 1;
 p := fej;
 while i <= l do
  begin
   if p=nil then
      begin
       getN := 0;
       exit;
      end;
   p := p^.f[s[i]];
   inc(i);
  end;
 if p <> nil then
     begin
      getN := p^.n;
      inc(i);
     end
    else getN := 0;
end;
 
procedure Remove(const s:string );inline;
var l:byte;
  function remove_rek( const p:PTrie;const i:byte ):boolean;
  var b:boolean;
  begin
   if i = l+1 then
     begin
      dec( p^.n );
     end
      else
     begin
      b := remove_rek( p^.f[ s[i] ] , i+1 );
      if b then
         begin
           dispose( p^.f[s[i]]);
           p^.f[s[i]] := nil;
         end;
     end;
   dec( p^.nr );
   remove_rek := p^.nr = 0;
  end;

begin
 l:= length(s);
 if remove_rek( fej,1 ) then
    begin
     dispose( fej^.f[s[1]] );
     fej^.f[s[1]] := nil;
    end;
end;

var c,c2:char;
    s:string;
    i:byte;
    rbuf: array[1..10000] of byte;
    wbuf: array[1..10000] of byte;
begin
 Create(fej);
 assign(input, 'trie.in');
 settextbuf(input,rbuf);
 reset(input);
 assign(output, 'trie.out');
 settextbuf(output,wbuf);
 rewrite(output);
 
 while not eof(input) do
  begin
   read(c,c2);
   readln(s);
   case c of
    '0': Add(s);
    '1': Remove(s);
    '2': writeln( getN(s,i) );
    '3': begin
               getN(s,i);
               writeln(i-2)
         end;
   end;
  end;
 close(output);
 close(input);
end.