Pagini recente » Cod sursa (job #1586457) | Cod sursa (job #421553) | Cod sursa (job #1984239) | Cod sursa (job #904629) | Cod sursa (job #1313975)
#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;
}
///Parser-------------------------------------------------------------------------------
int BUFFER_SIZE;
char *buffer;
int position = 0;
int tip;
char str[Lmax + 1];
inline char getChar()
{
if ( position < BUFFER_SIZE )
{
return buffer[ position++ ];
}
else
return '@';
}
int readQuery()
{
tip = 0;
char ch;
do
{
ch = getChar();
} while ( !isdigit( ch ) && !isalpha( ch ) );
do
{
tip = tip * 10 + ch - '0';
ch = getChar();
} while ( isdigit( ch ) );
do
{
ch = getChar();
} while ( !isdigit( ch ) && !isalpha( ch ) );
int n = 0;
do
{
str[ n++ ] = ch;
ch = getChar();
} while ( isalpha( ch ) );
assert( n <= Lmax );
str[n] = '\0';
return 1;
}
///-------------------------------------------------------------------------------------
///Test-------------------------------------------------------------------------------------
void validareTest()
{
ifstream in("trie.out");
ifstream ok("tests//grader_test19.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()
{
FILE *in = fopen("trie.in", "r");
FILE *out = fopen("trie.out", "w");
fseek(in, 0, SEEK_END);
BUFFER_SIZE = ftell(in);
fseek(in, 0, SEEK_SET);
buffer = new char[BUFFER_SIZE];
fread( buffer, BUFFER_SIZE, 1, in );
buffer[ BUFFER_SIZE-- ] = '\0';
initTrie();
do
{
readQuery();
switch ( tip )
{
case 0: insert( str ); break;
case 1: erase( str ); break;
case 2: fprintf(out, "%d\n", count( str )); break;
case 3: fprintf(out, "%d\n", prefix( str )); break;
}
} while ( position < BUFFER_SIZE );
fclose( in );
fclose( out );
///validareTest();
///malloc_stats(); /// MEMORY TEST
return 0;
}