Cod sursa(job #3173853)

Utilizator StefanL2005Stefan Leustean StefanL2005 Data 23 noiembrie 2023 20:01:14
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.39 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("trie.in");
ofstream out("trie.out");

struct thing{
    int pre = 0, entire = 0;
} A;

void Add_Word_To_Tree(int node, int p, string word, vector<vector<int>> &Vec, vector<vector<char>> &Cost, vector<thing> &Appear)
{
    Appear[node].pre++;
    if (word.length() == 0)
    {
        Appear[node].entire++;
        return;
    }

    for (int i = 0; i < Vec[node].size(); i++)
    {
        if (Vec[node][i] == p)
            continue;

        if (Cost[node][i] == word[0])
        {
            word.erase(word.begin());
            Add_Word_To_Tree(Vec[node][i], node, word, Vec, Cost, Appear);
            return;
        }
    }

    Vec[node].push_back(Vec.size());
    Vec.push_back(vector<int> (1, node));
    Cost[node].push_back(word[0]);
    Cost.push_back(vector<char> (1, word[0]));
    Appear.push_back(A);

    word.erase(word.begin());
    Add_Word_To_Tree(Vec.size() - 1, node, word, Vec, Cost, Appear);
}

void DeleteWord(int node, int p, string word, vector<vector<int>> &Vec, vector<vector<char>> &Cost, vector<thing> &Appear)
{
    Appear[node].pre = max(0, Appear[node].pre - 1);
    if (word.length() == 0)
    {
        Appear[node].entire = max(0, Appear[node].entire - 1);
        return;
    }

    for (int i = 0; i < Vec[node].size(); i++)
    {
        if (Vec[node][i] == p)
            continue;

        if (word[0] == Cost[node][i])
        {
            word.erase(word.begin());
            DeleteWord(Vec[node][i], node, word, Vec, Cost, Appear);
            return;
        }
    }
}

void Appearances(int node, int p, string word, vector<vector<int>> &Vec, vector<vector<char>> &Cost, vector<thing> &Appear)
{
    if (word.length() == 0)
    {
        out<< Appear[node].entire << "\n";
        return;
    }

    for (int i = 0; i < Vec[node].size(); i++)
    {
        if (Vec[node][i] == p)
            continue;

        if (word[0] == Cost[node][i])
        {
            word.erase(word.begin());
            Appearances(Vec[node][i], node, word, Vec, Cost, Appear);
            return;
        }
    }

    out<< 0 << "\n";
}

void PrefixAppear(int node, int p, string word, vector<vector<int>> &Vec, vector<vector<char>> &Cost, vector<thing> &Appear)
{
    int ans = 0;
    int Sum = Appear[node].pre;
    while (word.length() > 0 && Sum > 0)
    {
        bool Found = false;
        for (int i = 0; i < Vec[node].size(); i++)
        {
            if (Vec[node][i] == p)
                continue;

            if (word[0] == Cost[node][i])
            {
                word.erase(word.begin());
                Found = true;

                p = node;
                node = Vec[node][i];

                Sum = Appear[node].pre;
                if (Sum != 0)
                    ans++;

                break;
            }
        }

        if (!Found)
            break;
    }

    out<< ans << "\n";
}

int main()
{
    vector<vector<int>> Vec(1);
    vector<vector<char>> Cost(1);
    vector<thing> Appear(1, A);

    int Type;
    string Word;

    while (in>> Type)
    {   
        in>> Word;

        switch (Type)
        {
        case 0: { Add_Word_To_Tree(0, -1, Word, Vec, Cost, Appear); break; }
        case 1: { DeleteWord(0, -1, Word, Vec, Cost, Appear); break; }
        case 2: { Appearances(0, -1, Word, Vec, Cost, Appear); break; }
        case 3: { PrefixAppear(0, -1, Word, Vec, Cost, Appear); break; }
        }
    }

    return 0;
}