Cod sursa(job #839292)

Utilizator vendettaSalajan Razvan vendetta Data 21 decembrie 2012 17:09:22
Problema Trie Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

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

#define Lungtot 200000
#define Sigma 26
#define ll long long

struct camp{
    int dute, prefix;
    short int cuvant;
}T[Lungtot][Sigma];
string S;
int nr_tot = 0;

void baga(int nod, int poz){
    if (poz == S.size()) return;//daca am terminat ultimul caracter;

    int lit = S[poz]-'a';
    if (T[nod][lit].dute != 0){
        int unde = T[nod][lit].dute;
        T[unde][lit].prefix++;
        if (poz == S.size()-1) T[unde][lit].cuvant++;
        baga(T[nod][lit].dute, poz+1);
    }else {//nu a mai fost bagat
        T[nod][lit].dute = ++nr_tot;
        T[nr_tot][lit].prefix++;
        if ( poz == S.size()-1 ) T[nr_tot][lit].cuvant++;
        baga( T[nod][lit].dute, poz+1 );
    }
}

void sterge(int nod, int poz){//imi garanteaza ca cuvantul apare cel putin odata
    if ( poz == S.size() ) return;

    int lit = S[poz]-'a';
    int unde = T[nod][lit].dute;
    --T[unde][lit].prefix;
    if ( poz == S.size()-1 ) --T[unde][lit].cuvant;
    sterge(T[nod][lit].dute, poz+1);
}

void frecventa(int nod, int poz, int &cnt){//de cate ori apare cuvantul
    if ( poz == S.size()-1 ){//am ajung la cuvant
        int unde = T[nod][S[poz]-'a'].dute;
        cnt = T[unde][S[poz]-'a'].cuvant;
        return;
    }

    int lit = S[poz] - 'a';
    int unde = T[nod][lit].dute;
    if ( T[unde][lit].prefix > 0 ){
        frecventa(T[nod][lit].dute, poz+1, cnt);
    }else{// l-am sters
        cnt = 0;
        return;
    }
}

void lungime(int nod, int poz, int &cnt){
    if (poz == S.size()){
        return;
    }

    int lit = S[poz]-'a';
    int unde = T[nod][lit].dute;
    if (T[unde][lit].prefix > 0 ){
        lungime(T[nod][lit].dute, poz+1, cnt);
    }else {// pana aici mi-a fost
        return;
    }

    ++cnt;
}

void rezolva(){
    S.clear();
    for(; (getline(f,S))!=NULL; S.clear()){
        switch (S[0]-'0'){
            case 0:
                baga(0, 2);
                break;
            case 1:
                sterge(0, 2);
                break;
            case 2:{
                int cnt = 0;
                frecventa(0, 2, cnt);
                //cout << cnt << "\n";
                g << cnt << "\n";
                break;
            }
            case 3:{
                int cnt = 0;
                lungime(0, 2, cnt);
                g << cnt << "\n";
                //cout << cnt << "\n";
                break;
            }
        }
    }
}

int main(){

    rezolva();

    f.close();
    g.close();

    return 0;

}