Cod sursa(job #1962538)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 11 aprilie 2017 20:59:30
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>

using namespace std;
ifstream in("trie.in");
ofstream out("trie.out");

#define VAL cuv[ind] - 'a'
const int sigma = 26;

struct nodTrie {
    int app,nr;
    nodTrie *next[sigma];

    nodTrie() {
        nr = 0;
        app = 0;
        for (int i=0;i<26;++i) {
            next[i] = nullptr;
        }
    }
} start;
// start - primul nod din trie (care e asociat cu un cuvant nul)
// nodTrie = un nod din trie
// app - numarul de aparitii ale cuvantului ce se poate forma pe drumul de la start la nod
// nr - suma aparitiilor cuvintelor care trec prin nod
// next[i] - adresa urmatorului nod din trie, urmand o muchie determinata de a i-a litera din alfabet

void update(nodTrie*,const string&,int,int);
int queryApp(nodTrie*,const string&,int);
int queryMax(nodTrie*,const string&,int);
// update creste/scade numarul de aparitii ale unui cuvant,
//        stergand noduri daca niciun cuvant nu mai trece prin acestea
// queryApp - return-eaza numarul de aparitii ale unui cuvant,
//            urmand drumul de la start pana la nodul respectiv
// queryMax - return-eaza lungimea maxima a unui prefix al cuvantului
//            mergand de la start in jos cat este posibil

int main() {
    int tip;
    string cuv;

    in>>tip;
    while (!in.fail()) {
        in>>cuv;

        if (tip == 0 || tip == 1) {
            int add = (tip == 0) ? 1 : -1;
            update(&start,cuv,0,add);
        }
        else if (tip == 2) {
            out<<queryApp(&start,cuv,0)<<'\n';
        }
        else {
            out<<queryMax(&start,cuv,0)<<'\n';
        }

        in>>tip;
    }

    in.close();out.close();
    return 0;
}

void update(nodTrie *nod,const string& cuv,int ind,int add) {
    if ( (int)cuv.size() == ind ) {
        nod->app += add;
        nod->nr += add;
        return;
    }

    nodTrie *urm = nod->next[VAL];
    if (urm == nullptr) {
        urm = new nodTrie;
        nod->next[VAL] = urm;
    }

    update(urm,cuv,ind+1,add);
    nod->nr += add;

    if (urm->nr == 0) {
        delete urm;
        nod->next[VAL] = nullptr;
    }
}

int queryApp(nodTrie *nod,const string& cuv,int ind) {
    if ( (int)cuv.size() == ind ) {
        return nod->app;
    }

    nodTrie *urm = nod->next[VAL];
    if (urm == nullptr) {
        return 0;
    }
    return queryApp(urm,cuv,ind+1);
}

int queryMax(nodTrie *nod,const string& cuv,int ind) {
    nodTrie *urm = nod->next[VAL];

    if ( (int)cuv.size() == ind || urm == nullptr ) {
        return ind;
    }
    return queryMax(urm,cuv,ind+1);
}