#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
ifstream f("trie.in");
ofstream g("trie.out");
int c;
char cuv[21];
struct trie
{
int cuv, prefixe;
trie* litere[30];
trie()
{
cuv = 0;
prefixe = 0;
for (int i = 0; i < 30; i++)
litere[i] = 0;
}
};
void adaugare(trie* rad, char* cuv, int poz)
{
rad->prefixe++;
if (strlen(cuv) == poz)
{
rad->cuv++;
return;
}
int litera = cuv[poz] - 'a';
if (rad->litere[litera] == 0)
rad->litere[litera] = new trie;
adaugare(rad->litere[litera], cuv, poz + 1);
}
void stergere(trie* rad, char* c, int poz)
{
rad->prefixe--;
if (poz == strlen(c))
{
rad->cuv--;
return;
}
/// gasim litera din cuvantul de sters si continuam stergerea
int litera = c[poz] - 'a';
stergere(rad->litere[litera], c, poz + 1);
}
int nr_aparitii(trie* rad, char* cuv, int poz)
{
if (strlen(cuv) == poz)
{
return rad->cuv;
}
int litera = cuv[poz] - 'a';
if (rad->litere[litera] == 0 || rad->litere[litera]->prefixe == 0)
return 0;
nr_aparitii(rad->litere[litera], cuv, poz + 1);
}
int max_prefix(trie* rad, char* cuv, int poz)
{
if (strlen(cuv)==poz)
{
return strlen(cuv);
}
int litera = cuv[poz] - 'a';
if (rad->litere[litera] == 0 || rad->litere[litera]->prefixe == 0)
return poz;
max_prefix(rad->litere[litera], cuv, poz + 1);
}
int main()
{
int op;
char ch[21];
trie* rad = new trie;
while (f >> op >> ch)
{
switch (op)
{
case 0:
adaugare(rad, ch, 0);
break;
case 1:
stergere(rad, ch, 0);
break;
case 2:
g << nr_aparitii(rad, ch, 0) << '\n';
break;
case 3:
g << max_prefix(rad, ch, 0) << '\n';
break;
}
}
}