Cod sursa(job #2967001)

Utilizator iProgramInCppCluci Andrei iProgramInCpp Data 18 ianuarie 2023 21:07:05
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.38 kb
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

#define ARRAY_COUNT(arr) (int(sizeof(arr) / sizeof(*arr)))

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

struct TrieNode
{
    int m_apparitions = 0; // The apparitions of the word ending with this node.
    int m_prefix = 0;

    TrieNode* m_subNodes[26];

    TrieNode()
    {
        for (int i = 0; i < ARRAY_COUNT(m_subNodes); i++)
        {
            m_subNodes[i] = 0;
        }
    }
};

TrieNode root;

TrieNode* GetNode(const char* str, void(*processor)(TrieNode*) = nullptr, TrieNode* parent = &root)
{
    if (*str == 0) return parent;

    int index = *str - 'a';

    if (!parent->m_subNodes[index])
    {
        parent->m_subNodes[index] = new TrieNode;
    }

    if (processor)
        processor(parent->m_subNodes[index]);

    return GetNode(str+1, processor, parent->m_subNodes[index]);
}

void OnAdd(TrieNode* node)
{
    node->m_prefix++;
}

void Add(const char* chr)
{
    GetNode(chr, OnAdd)->m_apparitions++;
}

void OnRemove(TrieNode* node)
{
    node->m_prefix--;
}

void Remove(const char* chr)
{
    GetNode(chr, OnRemove)->m_apparitions--;
}

void QueryAppearance(const char* chr)
{
    fout << GetNode(chr)->m_apparitions << '\n';
}

// couldn't make use of GetNode so we'll duplicate and customize it.
void QueryLongestCommonPrefix(const char* str, int & maxlength, TrieNode* parent = &root, int length = 1)
{
    if (*str == 0) return;

    int index = *str - 'a';

    if (!parent->m_subNodes[index])
    {
        parent->m_subNodes[index] = new TrieNode;
    }

    if (parent->m_subNodes[index]->m_prefix > 0)
    {
        maxlength = max(maxlength, length);
    }

    QueryLongestCommonPrefix(str+1, maxlength, parent->m_subNodes[index], length + 1);
}

int main()
{
    int a, maxl; string b;
    while (fin >> a >> b)
    {
        switch (a)
        {
            case 0:
                Add(b.c_str());
                break;
            case 1:
                Remove(b.c_str());
                break;
            case 2:
                QueryAppearance(b.c_str());
                break;
            case 3:
                maxl = 0;
                QueryLongestCommonPrefix(b.c_str(), maxl);
                fout << maxl << '\n';
                break;
        }
    }

    return 0;
}