Cod sursa(job #668945)

Utilizator vendettaSalajan Razvan vendetta Data 25 ianuarie 2012 21:15:59
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.34 kb
#include <cstdio>
#define nmax 200001*26

using namespace std;

struct Trie{

    char c;//caracterul nodului
    int fiu, fr;//caracter de fiu respectiv frate
    int Ap, Ac;//numarul de aparitii al prefixului pana in aceasta pozitie inclusiv,
               //nr de aparitii al cuvantului daca se termina pe aceasta pozitie
} T[nmax];

char v[32];
int Nrn=0;//numarul de noduri ; Indexarea se face de la 0;

void adauga(){

    int r = 0;//radacina arborelui
    int k = 0;//pozitia ultimului copil
    int j, i;
    for(i=2; v[i]&&v[i]!='\n'; i++){//parcurg toata linia citita
        for(j=T[r].fiu; j; j=T[j].fr)//pentru fiecare copil al radacinii
            if (T[j].c == v[i]){
                T[j].Ap++;//marim numarul de aparitii a prefixului
                if (!v[i+1] || v[i+1] == '\n') T[j].Ac++;//daca cuvantul se termina pe aceasta pozitie marim nr de aparitii
                r = j;//trec la urmatorul caracter avandu-l pe j ca noua radacina a arborelui
                break;//ma opresc
            }else k = j;//inca caz ca nu gasesc caracterul stiu locul unde trebuie sa`l adaug(langa frate) :))
        if ( !j ){//daca nu gasesc caracterul il adaug
            Nrn++;//fac loc pentru noul caracter
            T[Nrn].c = v[i];//il salvez in arbore
            T[Nrn].Ap=1;//cresc numarul de aparitii
            if (!v[i+1] || v[i+1] == '\n') T[Nrn].Ac=1;else T[Nrn].Ac=0;//daca carac actual este si ultimul maresc aparitia cuvantului
            if (!T[r].fiu) T[r].fiu = Nrn;//daca radacina nu are fii il atribui pe caracterul actual
            else T[k].fr = Nrn;//daca are fii atunci il adaug ca si frate
            r = Nrn;//Nrn v`a deveni noua radacina;
        }
    }

}

void sterge(){

    int r = 0;
    int i, j;

    for(i=2; v[i]&&v[i]!='\n'; i++){
        for(j=T[r].fiu; j; j=T[j].fr)
            if (T[j].c == v[i]){
                T[j].Ap--;//Ii sterg o aparite a prefixului;
                if (!v[i+1] || v[i+1] == '\n') T[j].Ac--;//daca e cuvant ii sterg o aparitie
                r = j; //schimb radacina;
                break;
            }
    }

}

int ap_cuv(){

    int r = 0;
    int i, j;

    for(i=2; v[i]&&v[i]!='\n'; i++){
        for(j=T[r].fiu; j; j=T[j].fr)
            if (T[j].c == v[i] && T[j].Ap){//daca gasim caracterul
                r = j;
                if (!v[i+1] || v[i+1] == '\n') return T[j].Ac;//daca s-a terminat linia returnez Nr de aparitii al cuvantului
                break;
            }
        if ( !j ) return 0;
    }

    return 0;

}

int L_max(){

    int L = 0;
    int r = 0;
    int i,j;

    for(i=2; v[i]&&v[i]!='\n'; i++){
        for(j=T[r].fiu; j; j=T[j].fr)
            if (T[j].c == v[i] && T[j].Ap){
                L++;
                r = j;
                break;
            }
        if ( !j ) return L;
    }
    return L;

}

int main(){

    freopen("trie.in", "r", stdin);
    freopen("trie.out", "w", stdout);
/*
    while (!feof(stdin)){
        fgets(v, 32, stdin);
        if (!feof(stdin)){
  */
        while(fgets(v, 32, stdin)){
            if (v[0] == '0') adauga();
            if (v[0] == '1') sterge();
            if (v[0] == '2') printf("%d\n", ap_cuv());
            if (v[0] == '3') printf("%d\n", L_max());
        }

    fclose(stdin);
    fclose(stdout);

    return 0;

}