Cod sursa(job #2522242)

Utilizator IulianOleniucIulian Oleniuc IulianOleniuc Data 12 ianuarie 2020 10:52:33
Problema Aho-Corasick Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include <bits/stdc++.h>
using namespace std;

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

class Trie {
  private:
    struct Node {
        int frq, link, next[26];
    };

    vector<int> q, where;
    vector<Node> trie{2};

  public:
    void insert(string& str) {
        int node = 1;
        for (char chr : str) {
            int code = chr - 'a';
            if (!trie[node].next[code]) {
                trie[node].next[code] = trie.size();
                trie.emplace_back();
            }
            node = trie[node].next[code];
        }
        where.push_back(node);
    }

    void bfs() {
        q.push_back(1);
        trie[1].link = 1;
        for (int i = 0; i < (int) q.size(); i++) {
            int node = q[i];
            for (int code = 0; code < 26; code++)
                if (trie[node].next[code]) {
                    int temp = trie[node].link;
                    while (temp != 1 && !trie[temp].next[code])
                        temp = trie[temp].link;
                    if (trie[temp].next[code] && trie[temp].next[code] != trie[node].next[code])
                        temp = trie[temp].next[code];
                    q.push_back(trie[node].next[code]);
                    trie[trie[node].next[code]].link = temp;
                }
        }
    }

    vector<int> antiBFS(string& str) {
        int node = 1;
        for (char chr : str) {
            int code = chr - 'a';
            while (!trie[node].next[code] && node > 1)
                node = trie[node].link;
            if (trie[node].next[code])
                node = trie[node].next[code];
            trie[node].frq++;
        }
        for (int i = q.size() - 1; i > 0; i--)
            trie[trie[q[i]].link].frq += trie[q[i]].frq;

        vector<int> cnt(where.size());
        for (int i = 0; i < (int) where.size(); i++)
            cnt[i] = trie[where[i]].frq;
        return cnt;
    }
};

int main() {
    string str; fin >> str;
    int n; fin >> n;

    Trie trie;
    for (int i = 1; i <= n; i++) {
        string s; fin >> s;
        trie.insert(s);
    }

    trie.bfs();
    auto sol = trie.antiBFS(str);
    for (int i = 1; i <= n; i++)
        fout << sol[i] << '\n';

    fout.close();
    return 0;
}