Cod sursa(job #2739122)

Utilizator MatteoalexandruMatteo Verzotti Matteoalexandru Data 6 aprilie 2021 21:19:36
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.87 kb
/*
                `-/oo+/-   ``
              .oyhhhhhhyo.`od
             +hhhhyyoooos. h/
            +hhyso++oosy- /s
           .yoooossyyo:``-y`
            ..----.` ``.-/+:.`
                   `````..-::/.
                  `..```.-::///`
                 `-.....--::::/:
                `.......--::////:
               `...`....---:::://:
             `......``..--:::::///:`
            `---.......--:::::////+/`
            ----------::::::/::///++:
            ----:---:::::///////////:`
            .----::::::////////////:-`
            `----::::::::::/::::::::-
             `.-----:::::::::::::::-
               ...----:::::::::/:-`
                 `.---::/+osss+:`
                   ``.:://///-.
*/
#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << '\n'
#define debugsp(x) cerr << #x << " " << x << ' '

using namespace std;

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

const int INF = 2e9;
const int SIGMA = 26;

class Trie {
    private:
        struct Node {
            int ap, sz;
            Node* fii[1 + SIGMA];

            Node() {
                ap = sz = 0;
                for(int i = 1; i <= SIGMA; i++)
                    fii[i] = nullptr;
            }
        };
    public:
        Node* root;
        Trie() {
            root = new Node();
        }

        void Update(Node* &node, string s, int sz, int value) {
            if(sz == s.size()) {
                node -> ap += value;
                return;
            }

            if(node -> fii[s[sz] - 'a' + 1] == nullptr) {
                node -> sz++;
                node -> fii[s[sz] - 'a' + 1] = new Node();
            }

            Update(node -> fii[s[sz] - 'a' + 1], s, sz + 1, value);
            if(node -> fii[s[sz] - 'a' + 1] -> ap + node -> fii[s[sz] - 'a' + 1] -> sz == 0) {
                node -> sz--;
                node -> fii[s[sz] - 'a' + 1] = nullptr;
            }
        }

        int Count(Node* node, string s, int sz) {
            if(node == nullptr) return 0;
            if(sz == s.size()) return node -> ap;

            return Count(node -> fii[s[sz] - 'a' + 1], s, sz + 1);
        }

        int Longest_Prefix(Node* node, string s, int sz) {
            if(node == nullptr) return sz - 1;
            if(sz == s.size() || node -> sz == 0)
                return sz;
            return Longest_Prefix(node -> fii[s[sz] - 'a' + 1], s, sz + 1);
        }
};

int main() {
    Trie trie;
    int op;
    string s;

    while(in >> op >> s) {
        if(op == 0)
            trie.Update(trie.root, s, 0, 1);
        else if(op == 1)
            trie.Update(trie.root, s, 0, -1);
        else if(op == 2)
            out << trie.Count(trie.root, s, 0) << '\n';
        else if(op == 3)
            out << trie.Longest_Prefix(trie.root, s, 0) << '\n';
    }
    return 0;
}