Pagini recente » Cod sursa (job #301291) | Cod sursa (job #229873) | Cod sursa (job #668945)
Cod sursa(job #668945)
#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;
}