Cod sursa(job #1314011)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 11 ianuarie 2015 13:58:58
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.01 kb
#include <bits/stdc++.h>
#include <malloc.h>
 
using namespace std;
 
const int SIGMA = 26;
const int NR_CELLS = 115000;
const int Lmax = 20;
 
struct  __attribute__((__packed__)) List
{
    int node:18;
    int urm:18;
    char letter:6;
};
 
struct __attribute__((__packed__)) Trie
{
    int head:18;
 
    int nrAparitii:17;
    char nrSons:5;
 
    Trie(): head(0), nrAparitii(0), nrSons(0)
    {
    }
};
 
List Lista[NR_CELLS];
Trie T[NR_CELLS];
int root, size, contor;
 
void initTrie()
{
    root = 0;
    size = root + 1;
}
 
inline void addToList( const int node, const int val, const int letter )
{
    contor++;
    Lista[contor].node = val;
    Lista[contor].letter = letter;
    Lista[contor].urm = T[node].head;
    T[node].head = contor;
}
 
inline void eraseList( const int node )
{
    T[node].head = 0;
}
 
inline void eraseFromList( const int node, const int letter )
{
    if ( T[node].head == 0 )
        return;
 
    if ( Lista[ T[node].head ].letter == letter )
    {
        T[node].head = Lista[ T[node].head ].urm;
    }
    else
    {
        int pred = T[node].head;
 
        while ( Lista[ pred ].urm != 0 && Lista[ Lista[ pred ].urm ].letter != letter )
                pred = Lista[ pred ].urm;
 
        int deSters = Lista[ pred ].urm;
 
        Lista[ pred ].urm = Lista[ deSters ].urm;
    }
}
 
inline int NEXT( const int node, const int letter )
{
    int p = T[node].head;
 
    while ( p != 0 )
    {
        if ( Lista[p].letter == letter )
            return Lista[p].node;
 
        p = Lista[p].urm;
    }
 
    return 0;
}
 
void insert( char *s )
{
    int node = root;
 
    for ( ; *s; s++ )
    {
        int ch = *s - 'a';
        int urm = NEXT( node, ch );
 
        if ( urm == 0 )
        {
            urm = size++;
            addToList( node, urm, ch );
            T[node].nrSons++;
        }
 
        node = urm;
    }
 
    T[node].nrAparitii++;
}
 
int stiva[Lmax + 1];
int top;
 
void erase( char *s )
{
    int node = root;
    top = 0;
 
    for ( ; *s; s++ )
    {
        int ch = *s - 'a';
 
        node = NEXT( node, ch );
 
        assert( node != 0 );
 
        stiva[ ++top ] = node;
    }
 
    T[node].nrAparitii--;
 
    while ( T[node].nrAparitii == 0 && T[node].nrSons == 0 && node != root )
    {
        s--;
 
        eraseList( node );
 
        node = stiva[ --top ];
        eraseFromList( node, *s - 'a' );
        T[node].nrSons--;
    }
}
 
int count( char *s )
{
    int node = root;
 
    for ( ; *s; ++s )
    {
        int ch = *s - 'a';
        int urm = NEXT( node, ch );
 
        if ( urm == 0 )
            break;
        else
            node = urm;
    }
 
    if ( *s )
        return 0;
    else
        return T[node].nrAparitii;
}
 
int prefix( char *s )
{
    int sol = 0;
    int node = root;
 
    for ( ; *s; ++s )
    {
        int ch = *s - 'a';
        int urm = NEXT( node, ch );
 
        if ( urm == 0 )
            break;
        else
        {
            sol++;
            node = urm;
        }
    }
 
    return sol;
}
 
void validareTest()
{
    ifstream in("trie.out");
    ifstream ok("tests//grader_test20.ok");
 
    if ( !in || !ok )
    {
        cerr << "File output/ok missing!";
        exit( 0 );
    }
 
    int mySOl, correctSol;
 
    while( in >> mySOl )
    {
        ok >> correctSol;
 
        if ( mySOl != correctSol )
        {
            cerr << "Wrong Answer " << mySOl << " " << correctSol << "\n";
            exit( 0 );
        }
    }
 
    cerr << "Accepted\n";
 
    in.close();
    ok.close();
}
 
int main()
{
    freopen("trie.in", "r", stdin);
    freopen("trie.out", "w", stdout);
 
    initTrie();
 
    int tip;
    char s[Lmax + 1];
 
    while ( scanf( "%d %s", &tip, s ) == 2 )
    {
        switch ( tip )
        {
            case 0: insert( s ); break;
            case 1: erase( s ); break;
            case 2: printf("%d\n", count( s )); break;
            case 3: printf("%d\n", prefix( s )); break;
        }
    }
 
    fclose( stdin );
    fclose( stdout );
 
    ///validareTest();
    ///malloc_stats(); /// MEMORY TEST
 
    return 0;
}