Pagini recente » Cod sursa (job #2148735) | Cod sursa (job #823921) | Cod sursa (job #1104475) | Cod sursa (job #633349) | Cod sursa (job #3347870)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");
struct trie_node {
int frec; // number of words that end exactly here
int cnt; // number of words in subtree rooted here
trie_node* copii[26];
trie_node() : frec(0), cnt(0) {
for (int i = 0; i < 26; ++i) copii[i] = nullptr;
}
};
trie_node* rad = new trie_node;
inline int idx_of(char c) {
return c - 'a';
}
void adauga(const string &s) {
trie_node* nod = rad;
nod->cnt++; // root counts this insertion
for (char c : s) {
int idx = idx_of(c);
if (idx < 0 || idx >= 26) return; // defensive (shouldn't happen per statement)
if (nod->copii[idx] == nullptr)
nod->copii[idx] = new trie_node;
nod = nod->copii[idx];
nod->cnt++;
}
nod->frec++;
}
void sterge(const string &s) {
// first walk the path while recording nodes + indices
trie_node* nod = rad;
vector<pair<trie_node*, int>> path; // (node, idx used to go to child)
// decrement root's cnt immediately (we know the word exists by problem statement)
nod->cnt--;
for (char c : s) {
int idx = idx_of(c);
// defensive checks (should not trigger with valid input)
if (idx < 0 || idx >= 26) return;
trie_node* child = nod->copii[idx];
if (child == nullptr) return; // defensive: word not present (shouldn't happen)
path.emplace_back(nod, idx);
nod = child;
nod->cnt--;
}
// nod now points to final node for the word
if (nod->frec > 0) nod->frec--;
else return; // defensive: nothing to delete (shouldn't happen)
// free nodes from leaf upward if they became unused (cnt==0 and frec==0)
for (int i = (int)path.size() - 1; i >= 0; --i) {
trie_node* parent = path[i].first;
int idx = path[i].second;
trie_node* child = parent->copii[idx];
if (child && child->cnt == 0 && child->frec == 0) {
// child subtree is empty: delete node and cut link
delete child;
parent->copii[idx] = nullptr;
} else {
// if child still has words in subtree, stop deleting upwards
break;
}
}
}
int getCount(const string &s) {
trie_node* nod = rad;
for (char c : s) {
int idx = idx_of(c);
if (idx < 0 || idx >= 26) return 0; // defensive
if (nod->copii[idx] == nullptr) return 0;
nod = nod->copii[idx];
}
return nod->frec;
}
int longestPref(const string &s) {
trie_node* nod = rad;
int cnt = 0;
for (char c : s) {
int idx = idx_of(c);
if (idx < 0 || idx >= 26) break;
if (nod->copii[idx] == nullptr) break;
trie_node* child = nod->copii[idx];
if (child->cnt == 0) break; // no existing word in that subtree
nod = child;
++cnt;
}
return cnt;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
string s;
while (fin >> t >> s) {
switch (t) {
case 0: adauga(s); break;
case 1: sterge(s); break;
case 2: fout << getCount(s) << '\n'; break;
case 3: fout << longestPref(s) << '\n'; break;
default: break;
}
}
return 0;
}