Cod sursa(job #3351722)

Utilizator amavutsiviatamaulachitgaboriipetrusifilip amavutsiviata Data 21 aprilie 2026 09:34:24
Problema Trie Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.18 kb
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <array>
#include <climits>
#warning That's not NP, that's my NP!

using namespace std;
struct Trie {
    struct trie_node {
        int cnt = 0;
        vector<int> children;

        explicit trie_node () : children(26, -1) { }
    };

    vector<trie_node> tree;
    explicit Trie () : tree(1) { }

    void insert_word (const string& v) {
        int root = 0;
        tree[root].cnt++;
        for (auto c : v) {
            int c_idx = c - 'a';
            if (tree[root].children[c_idx] == -1) {
                int n_idx = tree.size();
                tree.emplace_back();
                tree[root].children[c_idx] = n_idx;
            }
            root = tree[root].children[c_idx];
            tree[root].cnt++;
        }
    }

    int get_tail (const string& v) {
        int root = 0;
        for (auto c : v) {
            int c_idx = c - 'a';
            if (tree[root].children[c_idx] == -1) {
                return -1;
            }
            root = tree[root].children[c_idx];
        }
        return root;
    }

    void remove_word (const string& v) {
        int root = 0;
        tree[root].cnt--;
        for (auto c : v) {
            int c_idx = c - 'a';
            assert(tree[root].children[c_idx] != -1);
            root = tree[root].children[c_idx];
            tree[root].cnt--;
        }
    }

    int count_occ (const string& v) {
        int tail = get_tail(v);
        if (tail == -1) {
            return 0;
        }
        int total_cnt = tree[tail].cnt;
        for (char c = 'a'; c <= 'z'; c++) {
            int c_idx = c - 'a';
            if (tree[tail].children[c_idx] != -1) {
                int new_root = tree[tail].children[c_idx];
                total_cnt -= tree[new_root].cnt;
            }
        }
        return total_cnt;
    }

    int get_lcp (const string& v) {
        int root = 0;
        int mx_len = 0;
        for (auto c : v) {
            int c_idx = c - 'a';
            if (tree[root].children[c_idx] == -1) {
                break;
            }
            int new_root = tree[root].children[c_idx];
            if (tree[new_root].cnt == 0) {
                break;
            }

            mx_len++;
            root = tree[root].children[c_idx];
        }
        return mx_len;
    }
};

int main () {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    ifstream cin("trie.in");
    ofstream cout("trie.out");

    int t;
    string w;
    Trie trie;
    while (cin >> t >> w) {
        if (t == 0) {
            trie.insert_word(w);
        } else if (t == 1) {
            trie.remove_word(w);
        } else if (t == 2) {
            cout << trie.count_occ(w) << "\n";
        } else {
            cout << trie.get_lcp(w) << "\n";
        }
    }

    return 0;
}