Cod sursa(job #2641242)

Utilizator PushkinPetolea Cosmin Pushkin Data 10 august 2020 17:15:51
Problema Trie Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.3 kb
#include <bits/stdc++.h>
using namespace std;

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

class Trie
{
    struct node///trie node
    {
        unsigned int info, children;
        node *next[26], *parent;///descendant nodes

        node()///node ctor
        {
            info=0;
            children=1;
            parent=NULL;
            for(unsigned int i=0; i<26; i++)
                next[i]=NULL;
        }
    }*r;///root of trie

public:

    Trie()///trie ctor
    {r=new node;}

    inline void add(string s)///adds one occurence of s to the trie
    {
        int i=-1;///because of the ++i in the while
        node *x=r;///auxiliary node for iterating

        while(++i!=s.size() && x->next[s[i]-'a']!=NULL)///search until end of word or node not allocated
            x=x->next[s[i]-'a'];

        if(i!=s.size())///word is not already in trie => new descendant
            x->children++;
        i--;///because of the ++i in the while

        while(++i!=s.size())///allocate new nodes until end of word
        {
            x->next[s[i]-'a']=new node;
            x->next[s[i]-'a']->parent=x;
            x=x->next[s[i]-'a'];
        }

        x->children--;///initialized as 1
        x->info++;///add occurence
    }

    inline void cut(string s)///removes one occurence of s from the trie
    {
        int i=-1;///because of the ++i in the while
        node *x=r;///auxiliary node for iterating

        while(++i!=s.size() && x->next[s[i]-'a']!=NULL)///search until end of word
            x=x->next[s[i]-'a'];

        x->info--;///delete occurence

        if(!x->info)///node has no occurences
        {
            while(x->children<2)///remove nodes until reaching a node with other descendants
            {
                int pos=s[--i]-'a';
                x=x->parent;
                delete x->next[pos];
                x->next[pos]=NULL;
            }
            x->children--;
        }
    }

    int operator[](string s)///returns number of occurences of s in the trie
    {
        int i=-1;///because of the ++i in the while
        node *x=r;///auxiliary node for iterating

        while(++i!=s.size() && x->next[s[i]-'a']!=NULL)///search until end of word or node not allocated
            x=x->next[s[i]-'a'];

        if(i!=s.size())///word not in trie
            return 0;

        return x->info;
    }

    inline int prefix(string s)///returns length of the longest prefix of s in the trie
    {
        int i=-1;///because of the ++i in the while
        node *x=r;///auxiliary node for iterating

        while(++i!=s.size() && x->next[s[i]-'a']!=NULL)///search until end of word or node not allocated
            x=x->next[s[i]-'a'];

        return i;
    }
}T;

void solve()
{
    unsigned int op;
    string s;

    int aux=0;

    while(f>>op>>s)
    {
        if(aux==8000)
        {

            aux=8000;


        }
        switch(op)
        {
            case 0: T.add(s); break;
            case 1: T.cut(s); break;
            case 2: g<<T[s]<<'\n';break;
            case 3: g<<T.prefix(s)<<'\n';break;
            default: cout<<"ERROR: wrong opcode!\n";
        }
        aux;
    }
}

int main()
{
    solve();
    f.close();
    g.close();
    return 0;
}