Cod sursa(job #2762867)

Utilizator AndreiDeltaBalanici Andrei Daniel AndreiDelta Data 9 iulie 2021 18:31:14
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.62 kb
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
ifstream f("trie.in");
ofstream g("trie.out");
typedef long long ll;
typedef pair<int,int> pi;
int t,T;

class Node
{
    #define ABC 26

private:
    int occ,fii;
    Node* next[ABC];

public:
    Node():occ{0},fii{0}{
        for(int i=0;i<ABC;i++) next[i]=NULL;
    }

    int get_occ() const noexcept{
        return occ;
    }

    int get_fii() const noexcept{
        return fii;
    }

    Node* get_ptr_letter(char letter) const noexcept{
        return next[letter-'a'];
    }

    void set_next_letter(char letter,Node* ptr){
        if(ptr==NULL && next[letter-'a']!=NULL) fii--;
        else
        if(ptr!=NULL && next[letter-'a']==NULL) fii++;
        next[letter-'a']=ptr;
    }

    void inc_occ(){
        occ++;
    }

    void dec_occ(){
        occ--;
    }

    ~Node()=default;

};

Node* root;

//rad-radacina de care o sa mi leg caracterul de pe pozitia poza
void add_word(Node* rad,const string& S,int poz)
{
    if(poz==S.size())
    {
        rad->inc_occ();
        return;
    }
    char letter=S[poz];
    if(rad->get_ptr_letter(letter)==NULL)
    {
        Node* nod=new Node;
        rad->set_next_letter(letter,nod);
    }
    add_word(rad->get_ptr_letter(letter),S,poz+1);
}


bool delete_word(Node* rad,const string& S,int poz)
{
    if(poz==S.size()) rad->dec_occ();
    else
    {
        if(delete_word(rad->get_ptr_letter(S[poz]),S,poz+1))
            rad->set_next_letter(S[poz],NULL);

    }
    if(rad!=root && !rad->get_occ() && !rad->get_fii())
    {
        delete rad;
        return 1;
    }
    return 0;
}

int occurences(Node* rad,const string& S,int poz)
{
    if(rad==NULL)
        return 0;
    if(poz==S.size())
        return rad->get_occ();
    return occurences(rad->get_ptr_letter(S[poz]),S,poz+1);
}

int longest_prefix(Node* rad,const string& S,int poz)
{
    //se termina cuvanul desi mai este ramura
    //sau nu mai este ramura

    if(poz==S.size() || rad->get_ptr_letter(S[poz])==NULL)
        return 0;

    return 1+longest_prefix(rad->get_ptr_letter(S[poz]),S,poz+1);

}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int op;
    string S;
    root=new Node;
    while( f>>op>>S)
    {

        if(op==0)
            add_word(root,S,0);
        else
        if(op==1)
            delete_word(root,S,0);
        else
        if(op==2)
            g<<occurences(root,S,0)<<'\n';
        else
            g<<longest_prefix(root,S,0)<<'\n';

    }
    delete root;
    return 0;
}