Cod sursa(job #2416357)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 27 aprilie 2019 14:04:15
Problema Aho-Corasick Scor 100
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 2.91 kb
#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
// 217
// 44

using namespace std;


struct Aho {

    struct Node {

        Node *son[26], *fail;
        int cnt;
        vector <int> pos;

        Node() {
            memset(son, NULL, sizeof(son));
            fail = NULL;
            cnt = 0;
        }

    };

    Node *root = new Node;

    void add(Node *nod, string &str, int p, int id) {

        if(p == str.size()) {
            nod -> pos.push_back(id);
        }
        else {
            char ch = str[p] - 'a';

            if(nod -> son[ch] == NULL) {
                nod -> son[ch] = new Node;
            }

            add(nod -> son[ch], str, p + 1, id);
        }

    }

    void add(string &str, int id) {

        add(root, str, 0, id);

    }

    vector <Node *> Q;

    void make_fail() {

        root -> fail = root;

        int p = 0;
        Q.push_back(root);

        while(p < Q.size()) {

            auto cur = Q[p++];

            for(int ch = 0; ch < 26; ch++) {

                if(cur -> son[ch] == NULL) {
                    continue;
                }

                auto aux = cur -> fail;

                while(aux != root && aux -> son[ch] == NULL) {
                    aux = aux -> fail;
                }

                if(aux -> son[ch] == NULL || aux == cur) {
                    cur -> son[ch] -> fail = aux;
                }
                else {
                    cur -> son[ch] -> fail = aux -> son[ch];
                }

                Q.push_back(cur -> son[ch]);

            }

        }

    }

    inline void compute(string &str) {

        Node *nod = root;

        for(auto it : str) {

            char ch = it - 'a';

            while(nod != root && nod -> son[ch] == NULL) {
                nod = nod -> fail;
            }

            if(nod -> son[ch] != NULL) {
                nod = nod -> son[ch];
            }

            nod -> cnt++;

        }

    }

    inline void solve(vector <int> &sol) {

        while(Q.size()) {

            auto cur = Q.back();
            Q.pop_back();

            for(auto it : cur -> pos) {
                sol[it] += cur -> cnt;
            }

            cur -> fail -> cnt += cur -> cnt;

        }

    }

};

int main() {
    ifstream cin("ahocorasick.in");
    ofstream cout("ahocorasick.out");
    int i, n;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    string str;
    cin >> str >> n;

    Aho aho;

    for(i = 0; i < n; i++) {
        string cur;
        cin >> cur;
        aho.add(cur, i);
    }

    aho.make_fail();

    aho.compute(str);

    vector <int> sol(n);
    aho.solve(sol);

    for(auto it : sol) {
        cout << it << "\n";
    }

    cin.close();
    cout.close();
    return 0;
}