Cod sursa(job #2470530)

Utilizator ApostolIlieDanielApostol Daniel ApostolIlieDaniel Data 9 octombrie 2019 13:19:43
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <bits/stdc++.h>

using namespace std;

const int LL = 1e6, L = 1000, N = 100;

char a[1 + LL + 1];
char s[1 + N][1 + L + 1];
int nr;
int ll;
const int ALPHA = 26;
struct Node {
    int nxt[ALPHA];
    int fail;
    int val;
};
Node trie[1 + L * N];
int l[1 + N];
int f[1 + N];
void add_word (int node, int ind, int pos) {
    if (pos > l[ind]) {
        f[ind] = node;
        return;
    }
    if (!trie[node].nxt[s[ind][pos] - 'a'])
        trie[node].nxt[s[ind][pos] - 'a'] = ++nr;
    add_word (trie[node].nxt[s[ind][pos] - 'a'], ind, pos + 1);
}
vector <int> ord;
#define pb push_back

void build_fail () {
    queue <int> q;
    for (int i = 0; i < ALPHA; i++)
        if (trie[0].nxt[i])
            q.push (trie[0].nxt[i]);
    while (q.size ()) {
        int node = q.front ();
        q.pop ();
        ord.pb (node);
        for (int i = 0; i < ALPHA; i++)
            if (trie[node].nxt[i]) {
                int vec = trie[node].nxt[i];
                q.push (vec);
                trie[vec].fail = trie[node].fail;
                while (trie[vec].fail && !trie[trie[vec].fail].nxt[i])
                    trie[vec].fail = trie[trie[vec].fail].fail;
                if (trie[trie[vec].fail].nxt[i])
                    trie[vec].fail = trie[trie[vec].fail].nxt[i];
            }
    }
}

void solve () {
    int node = 0;
    for (int i = 1; i <= ll; i++) {
        while (node && !trie[node].nxt[a[i] - 'a'])
            node = trie[node].fail;
        if (trie[node].nxt[a[i] - 'a'])
            node = trie[node].nxt[a[i]-'a'];
        trie[node].val++;
    }
}
void anti_bfs () {
    for (int i = ord.size () - 1; i >= 0; i--) {
        int node = ord[i];
        trie[trie[node].fail].val += trie[node].val;
    }
}
int n;

int main() {
    freopen ("ahocorasick.in", "r", stdin);
    freopen ("ahocorasick.out", "w", stdout);
    ios::sync_with_stdio (false);
    cin.tie (0); cout.tie (0);

    cin >> (a + 1);
    ll = strlen (a + 1);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> (s[i] + 1);
        l[i] = strlen (s[i] + 1);
        add_word (0, i, 1);
    }

    build_fail ();

    solve ();

    anti_bfs ();

    for (int i = 1; i <= n; i++)
        cout << trie[f[i]].val << "\n";

    return 0;
}