Pagini recente » Borderou de evaluare (job #1951437) | Borderou de evaluare (job #1940114) | Borderou de evaluare (job #1768195) | Borderou de evaluare (job #1100932) | Cod sursa (job #3347876)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");
struct trie_node{
int frec, cnt;
trie_node* copii[30];
trie_node() {
frec=cnt=0;
for(int i=0;i<30;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(string s){
trie_node* nod=rad;
for(auto c: s){
nod=nod->copii[c-'a'];
}
return nod->frec;
}
int longestPref(string s){
trie_node* nod=rad;
int cnt=0;
for(auto c: s){
if(nod->copii[c-'a'] == nullptr){
break;
}
if(nod->copii[c-'a']->cnt==0)
break;
nod=nod->copii[c-'a'];
cnt++;
}
return cnt;
}
int main()
{
int t;
string s;
while(fin>>t>>s){
if(t==0){
adauga(s);
}
if(t==1){
sterge(s);
}
if(t==2){
cout<<getCount(s)<<'\n';
}
if(t==3){
cout<<longestPref(s)<<'\n';
}
}
return 0;
}