Pagini recente » Cod sursa (job #3297612) | Cod sursa (job #3358935) | Cod sursa (job #3359328) | Cod sursa (job #1305563) | Cod sursa (job #3358930)
// https://www.infoarena.ro/problema/trie
// trie clasic cu copii pe array de 26
// pass = cate cuvinte trec prin nod (pentru prefix si pentru stergerea nodurilor ramase libere)
// cnt = cate cuvinte se termina exact in nod
// operatii: 0 = adauga, 1 = sterge, 2 = numara aparitiile, 3 = lungimea celui mai lung prefix comun
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");
struct node {
node *ch[26];
int cnt;
int pass;
};
node *make_node() {
node *n = new node;
for (int i = 0; i < 26; i++) n->ch[i] = nullptr;
n->cnt = 0;
n->pass = 0;
return n;
}
void add(node *root, const string &w) {
node *p = root;
for (char c : w) {
int k = c - 'a';
if (!p->ch[k]) p->ch[k] = make_node();
p = p->ch[k];
p->pass++;
}
p->cnt++;
}
void erase(node *root, const string &w) {
node *path[22];
int idx[22];
node *p = root;
int d = 0;
for (char c : w) {
int k = c - 'a';
path[d] = p;
idx[d] = k;
p = p->ch[k];
d++;
}
p->cnt--;
// scadem pass de jos in sus si stergem nodurile prin care nu mai trece niciun cuvant
for (int i = d - 1; i >= 0; i--) {
node *child = path[i]->ch[idx[i]];
child->pass--;
if (child->pass == 0) {
delete child;
path[i]->ch[idx[i]] = nullptr;
}
}
}
int count_word(node *root, const string &w) {
node *p = root;
for (char c : w) {
int k = c - 'a';
if (!p->ch[k]) return 0;
p = p->ch[k];
}
return p->cnt;
}
int longest_prefix(node *root, const string &w) {
node *p = root;
int len = 0;
for (char c : w) {
int k = c - 'a';
if (!p->ch[k]) break;
p = p->ch[k];
len++;
}
return len;
}
int main() {
node *root = make_node();
int op;
string w;
while (fin >> op >> w) {
if (op == 0) add(root, w);
else if (op == 1) erase(root, w);
else if (op == 2) fout << count_word(root, w) << '\n';
else if (op == 3) fout << longest_prefix(root, w) << '\n';
}
return 0;
}