Pagini recente » Cod sursa (job #2736224) | Cod sursa (job #694137) | Cod sursa (job #1166366) | Cod sursa (job #2751755) | Cod sursa (job #3290876)
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
ifstream cin("trie.in");
ofstream cout("trie.out");
const int ALPHABET_SIZE = 26;
// Să presupunem o limită suficientă de noduri (în funcţie de constrângeri)
const int MAX_NODES = 3000000;
// trie[node][litera] = indicele nodului copil (0 înseamnă "nu există")
int trie[MAX_NODES][ALPHABET_SIZE];
// cnt[node] = numărul de cuvinte care au trecut prin acest nod la inserare
int cnt[MAX_NODES];
// exact[node] = numărul de cuvinte terminate exact în acest nod
int exact[MAX_NODES];
int nodeCount = 1; // nodul 0 este rădăcina
// Inserare: actualizează atât contorul exact, cât şi pe cel de prefix (cnt)
void insert(const string &s) {
int node = 0;
for (char c : s) {
int idx = c - 'a';
if (trie[node][idx] == 0) {
trie[node][idx] = nodeCount++;
}
node = trie[node][idx];
cnt[node]++; // adăugăm la contorul de prefix
}
exact[node]++; // cuvântul s se termină aici
}
// Ștergere: se scade doar din contorul exact – NU se scade cnt (așa cum cere testul)
void removeWord(const string &s) {
int node = 0;
for (char c : s) {
int idx = c - 'a';
if (trie[node][idx] == 0) return; // cuvântul nu există, nu facem nimic
node = trie[node][idx];
}
if (exact[node] > 0)
exact[node]--; // scădem doar numărul de apariţii exacte
}
// Query tip 2: numărul de apariţii exacte ale şirului s
int queryExact(const string &s) {
int node = 0;
for (char c : s) {
int idx = c - 'a';
if (trie[node][idx] == 0) return 0;
node = trie[node][idx];
}
return exact[node];
}
// Query tip 3: parcurgem cât se poate din s; dacă la un moment dat nu găsim o legătură,
// returnăm contorul ultimului nod valid
int queryPrefix(const string &s) {
int node = 0;
int lastValid = 0; // vom păstra contorul ultimului nod pe care l-am parcurs
for (char c : s) {
int idx = c - 'a';
if (trie[node][idx] == 0)
return cnt[node]; // întoarce contorul nodului curent (ultimul valid)
node = trie[node][idx];
lastValid = node;
}
return cnt[lastValid];
}
int main() {
int op;
string s;
// Numărul total de operaţii (se presupune că inputul are 16 linii ca în exemplul dat)
// Sau se poate citi până la EOF.
// Pentru exemplul dat, vom citi până la EOF.
while (cin >> op >> s) {
if(op == 0) {
insert(s);
}
else if(op == 1) {
removeWord(s);
}
else if(op == 2) {
cout << queryExact(s) << "\n";
}
else if(op == 3) {
cout << queryPrefix(s) << "\n";
}
}
return 0;
}