Cod sursa(job #2761394)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 2 iulie 2021 01:53:57
Problema Trie Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.06 kb
#include <bits/stdc++.h>

using namespace std;

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

struct node {
    int counter;

    node() : counter(0) {
        for( int i = 0; i < 26; ++i )
            next[i] = NULL;
    }

    node *next[26];
};

node *root;

void Insert( string s ) {
    node *p = root;

    for( int i = 0; i < s.size(); ++i ) {
        int target = s[i] - 'a';

        if( p -> next[target] == NULL )
            p -> next[target] = new node;

        p = p -> next[target];
    }

    p -> counter++;
}

int LongestSubstring( string s ) {
    node *p = root;
    int ans = 0;

    for( int i = 0; i < s.size(); ++i ) {
        if( p -> next[s[i] - 'a'] == NULL )
            break;

        p = p -> next[s[i] - 'a'];
        ans = i + 1;
    }

    return ans;
}

bool Ending( node *p ) {
    for( int i = 0; i < 26; ++i )
        if( p -> next[i] != NULL )
            return false;
    return true;
}

void Delete( string s ) {
    vector <node*> v;
    node *p = root;

    for( int i = 0; i < s.size(); ++i ) {
        p = p -> next[ s[i] - 'a' ];

        v.push_back( p );
    }

    p -> counter--;

    int idx = s.size() - 1;
    while( v.size() > 0 && Ending( v.back() ) && v.back() -> counter == 0 ) {
        delete v.back();
        node *prev;
        if( v.size() > 1 ) prev = v[v.size() - 2];
        else prev = root;

        prev -> next[s[idx] - 'a'] = NULL;

        --idx;
        v.pop_back();
    }
}

void Delete2( string s ) {
    vector <node*> v;
    node *p = root;

    for( int i = 0; i < s.size(); ++i ) {
        p = p -> next[ s[i] - 'a' ];

        v.push_back( p );
    }

    p -> counter--;

    int idx = s.size() - 1;
    while( v.size() > 0 && Ending( p ) && p -> counter == 0 ) {
        delete p;
        node *prev;
        if( v.size() > 1 ) prev = v[v.size() - 2];
        else prev = root;

        prev -> next[s[idx] - 'a'] = NULL;

        --idx;
        v.pop_back();
    }
}

int Count( string s ) {
    node *p = root;

    for( int i = 0; i < s.size(); ++i ) {
        if( p -> next[s[i] - 'a'] == NULL )
            return 0;

        p = p -> next[s[i] - 'a'];
    }

    return p -> counter;
}

void Dfs( string &mzg, node *p ) {
    for( int i = 0; i < 26; ++i )
        if( p -> next[i] != NULL ) {
            mzg.push_back( char('a' + i) );
            Dfs( mzg, p -> next[i] );
            mzg.pop_back();
        }
    if( p -> counter )
        fout << mzg << '\n';
}

int main()
{
    root = new node;

    string w;
    int op;

    int cnt = 0;
    while( fin >> op >> w ) {
        ++cnt;
        if( cnt == 3657) {
            Delete2( w );
            break;
        }
        if( op == 0 )
            Insert( w );
        if( op == 1 )
            Delete( w );
        if( op == 2 )
            fout << Count( w ) << '\n';
        if( op == 3 )
            fout << LongestSubstring( w ) << '\n';
    }
    string ww = "";

    //Dfs( ww, root );

    return 0;
}