Cod sursa(job #2331842)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 29 ianuarie 2019 23:59:25
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.82 kb
#include <bits/stdc++.h>

struct trie_node {
    trie_node() {
        fail = NULL; count = 0;
        for (int i=0; i<30; ++i)
            sons[i] = NULL;
    }   int count;
    trie_node *fail, *sons[30];
    std::vector <int> endstr;
};

template <typename NodeType>
class AhoCorasick {
    public:
        AhoCorasick() {Root = new NodeType;}
        std::string Str;

        void Build() {
            BuildQueue.push(Root);
            Root->fail = Root;
            NodeType *p, *node;

            while (!BuildQueue.empty()) {
                p = BuildQueue.front();
                BuildQueue.pop();

                Order.push_back(p);

                for (int i=0; i<30; ++i)
                    if (p->sons[i] != NULL) {
                        node = p->fail;
                        while (node != Root && node->sons[i] == NULL)
                            node = node->fail;
                        if (node->sons[i] != NULL && node->sons[i] != p->sons[i])
                            node = node->sons[i];

                        p->sons[i]->fail = node;
                        BuildQueue.push(p->sons[i]);
                    }
            }   Root->fail = NULL;
        }

        void Compute(int Count[]) {
            NodeType *p = Root;
            for (int i=0, son; i<Str.size(); ++i) {
                son = Str[i] - 'a';
                while (p->sons[son] == NULL && p != Root)
                    p = p->fail;
                if (p->sons[son] != NULL)
                    p = p->sons[son];
                p->count ++;
            }

            for (int i=Order.size()-1; i>=0; --i) {
                p = Order[i];
                if (p->fail != NULL)
                    p->fail->count += p->count;
                for (auto it:p->endstr)
                    Count[it] = p->count;
            }
        }

        void insert(const std::string &str, int idx) {
            NodeType *ptr = Root;
            for (int i=0, son=0; i<str.size(); ++i, ptr = ptr->sons[son]) {
                son = str[i] - 'a';
                if (ptr->sons[son] == NULL)
                    ptr->sons[son] = new NodeType;
            }   ptr->endstr.push_back(idx);
        }

    private:
        NodeType *Root;
        std::queue <NodeType*> BuildQueue;
        std::vector <NodeType*> Order;
};  AhoCorasick <trie_node> AC;

#define MAXN 105

int N, Count[MAXN];
std::string str[MAXN];

std::ifstream In("ahocorasick.in");
std::ofstream Out("ahocorasick.out");

void Citire() {
    In >> AC.Str >> N;
    for (int i=0; i<N; ++i)
        In >> str[i], AC.insert(str[i], i);
}

void Rezolvare() {
    AC.Build();
    AC.Compute(Count);
    for (int i=0; i<N; ++i, Out << '\n')
        Out << Count[i];
}

int main()
{
    Citire();
    Rezolvare();

    return 0;
}