Cod sursa(job #710701)

Utilizator vendettaSalajan Razvan vendetta Data 10 martie 2012 16:35:04
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.87 kb
#include <cstdio>
#include <cstring>
#include <vector>
#define nmax 200005*26

using namespace std;

vector<int> gf[nmax];
struct camp{

    char c;
    int pr, cuv;

}Tr[nmax];
int Cnt = 1;
char s[32];
int L;

void built(int st){

    int nod = 1;

    for(int i=st; i<=L; i++){
        int ok = 0;
        for(int j=0; j<gf[nod].size(); j++){
            int vc = gf[nod][j];
            if (Tr[vc].c == s[i]){
                ok = 1;
                Tr[vc].pr++;
                if ( i == L ) Tr[vc].cuv++;
                nod = vc;//inca nu`s sigur; oricum urm pas vizitez vecinii vecinului(adica nodul("radacina") devine vecinul actual)
                break;
            }
        }
        //daca caracterul "s[i]" nu a mai fost folosit
        if (ok == 0){
            ++Cnt;
            gf[nod].push_back(Cnt);
            Tr[Cnt].c = s[i];
            Tr[Cnt].pr = 1;
            if (i == L ) Tr[Cnt].cuv = 1;
            nod = Cnt;
        }
    }

}

void sterge(int st){

    int nod = 1;

    for(int i=st; i<=L; i++){
        int ok = 0;
        for(int j=0; j<gf[nod].size(); j++){
            int vc = gf[nod][j];
            if (Tr[vc].c == s[i]){
                ok = 1;
                --Tr[vc].pr;
                if (i == L) Tr[vc].cuv--;
                nod = vc;
                break;
            }
        }
        if (ok == 0) return;//daca nu am gasit cuvantul
    }

}

int ap_cuv(int st){

    int nod = 1;

    for(int i=st; i<=L; i++){
        int ok=0;
        for(int j=0; j<gf[nod].size(); j++){
            int vc = gf[nod][j];
            if (Tr[vc].c == s[i] && Tr[vc].pr){//daca gasesc caracterul si a mai ramas macar o aparitie a lui
                ok = 1;
                if (i == L) return Tr[vc].cuv;
                nod = vc;
            }
        }
        if (ok == 0) return 0;
    }
    return 0;

}

int prefix_max(int st){

    int nod = 1;
    int lg = 0;//am nevoie de lungimea celui mai lung prefix , nu de nr de aparitii !!!

    for(int i=st; i<=L; i++){
        int ok = 0;
        for(int j=0; j<gf[nod].size(); j++){
            int vc = gf[nod][j];
            if (Tr[vc].c == s[i] && Tr[vc].pr){
                ok = 1;
                ++lg;
                nod = vc;
            }
        }
        if (ok == 0) return lg;
    }

    return lg;

}

int main(){

    freopen("trie.in", "r", stdin);
    freopen("trie.out", "w", stdout);

    while (fgets(s, 32, stdin)) {
        L = strlen(s) - 2;
        if (s[0] == '0') built(2);
        else if (s[0] == '1') sterge(2);
        else if (s[0] == '2') printf("%d\n", ap_cuv(2));
        else if (s[0] == '3') printf("%d\n", prefix_max(2));
    }
/*
    for(int i=1; i<=Cnt; i++){
        printf("vecinii lui %d : ", i);
        for(int j=0; j<gf[i].size(); j++){
            int vc = gf[i][j];
            printf("%d : %c ", vc, Tr[vc].c);
        }
        printf("\n");
    }
*/
    fclose(stdin);
    fclose(stdout);

}