Cod sursa(job #411676)

Utilizator hungntnktpHungntnktp hungntnktp Data 5 martie 2010 03:01:00
Problema Trie Scor 45
Compilator fpc Status done
Runda Arhiva educationala Marime 2.25 kb
{FP}
{$M 64000000,0}
{$MODE OBJFPC}
{$IFDEF ANHDQ}
  {$INLINE OFF}
  {$H-,I+,Q+,R+,S+}
{$ELSE}
  {$INLINE ON}
  {$H+,I-,Q-,R-,S-}
{$ENDIF}

// Result:
program trie_AnhDQ;

const
  FI_NAME = 'trie.in';
  FO_NAME = 'trie.out';
  MaxN    = 111111;

type
  TNode = record
            midCount, endCount: LongInt;
            Next              : array['a'..'z'] of LongInt;
          end;

var
  k, len, cnt, res: LongInt;
  w               : string;
  T               : array[0..MaxN] of TNode;
(*------------------------------*)
  procedure ReadQuery(); inline;
  begin
    read(k);
    SeekEOLn();
    ReadLn(w);
    len := Length(w);
  end;
(*------------------------------*)
  procedure Add(node, i: LongInt); inline;
  begin
    if T[node].Next[w[i]] = 0 then
    begin
      Inc(cnt);
      T[node].Next[w[i]] := cnt;
    end;
    Inc(T[T[node].Next[w[i]]].midCount);
    if i = len then Inc(T[T[node].Next[w[i]]].endCount)
    else Add(T[node].Next[w[i]], i + 1);
  end;
(*------------------------------*)
  procedure Del(node, i: LongInt); inline;
  begin
    if T[node].Next[w[i]] = 0 then exit;
    Dec(T[T[node].Next[w[i]]].midCount);
    if i = len then Dec(T[T[node].Next[w[i]]].endCount)
    else Del(T[node].Next[w[i]], i + 1);
  end;
(*------------------------------*)
  procedure Count(node, i: LongInt); inline;
  begin
    if T[node].Next[w[i]] = 0 then exit;
    if i = len then res := T[T[node].Next[w[i]]].endCount
    else Count(T[node].Next[w[i]], i + 1);
  end;
(*------------------------------*)
  procedure Count2(node, i: LongInt); inline;
  begin
    if (T[node].Next[w[i]] = 0) or (T[T[node].Next[w[i]]].midCount = 0) then
      res := i - 1
    else if i = len then res := i
         else Count2(T[node].Next[w[i]], i + 1);
  end;
(*------------------------------*)
begin
  Assign(Input, FI_NAME); Reset(Input);
  Assign(Output, FO_NAME); Rewrite(Output);
  while not SeekEOF() do
  begin
    ReadQuery();
    case k of
      0: Add(0, 1);
      1: Del(0, 1);
      2: begin
           res := 0;
           Count(0, 1);
           WriteLn(res);
         end;
      3: begin
           res := 0;
           Count2(0, 1);
           WriteLn(res);
         end;
    end;
  end;
end.