Cod sursa(job #3239443)

Utilizator _andrei4567Stan Andrei _andrei4567 Data 5 august 2024 16:47:31
Problema Aho-Corasick Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.02 kb
#include <fstream>
#include <queue>

using namespace std;

ifstream cin ("ahocorasick.in");
ofstream cout ("ahocorasick.out");

const int M = 1e6;
const int N = 100;
int rez[N + 1];

bool f[M + 1];

struct trie
{
    int dp, index, nr;
    bool isleaf;
    trie *children[26], *suff_link;
    trie (int x = 0)
    {
        dp = 0;
        index = -1;
        nr = x;
        isleaf = false;
        suff_link = nullptr;
        for (int i = 0; i < 26; ++i)
            children[i] = nullptr;
    }
};

trie *root = new trie();

string a, s;

int n, poz, t;

void add_word (trie *root, string s)
{
    for (auto it : s)
    {
        int ch = it - 'a';
        if (root->children[ch] == nullptr)
            root->children[ch] = new trie(++t);
        root = root->children[ch];
    }
    root->isleaf = 1;
    root->index = poz;
}

trie* suff (trie *aux, int poz)
{
    if (aux == root && aux->children[poz] != nullptr)
        return aux->children[poz];
    while (aux != root)
    {
        aux = aux->suff_link;
        if (aux->children[poz] != nullptr)
            return aux->children[poz];
    }
    return aux;
}

void bfs (trie *root)
{
    queue <trie*> q;
    for (int i = 0; i < 26; ++i)
        if (root->children[i] != nullptr)
            root->children[i]->suff_link = root, q.push(root->children[i]);
    while (!q.empty())
    {
        trie *aux = q.front();
        q.pop();
        for (int i = 0; i < 26; ++i)
            if (aux->children[i] != nullptr)
            {
                aux->children[i]->suff_link = suff(aux, i);
                q.push(aux->children[i]);
            }
    }

}

void go_up (trie *root)
{
    while (root->suff_link != nullptr)
    {
        if (root->nr == 1);
        root->suff_link->dp += root->dp;
        root = root->suff_link;
    }
}

void dfs (trie *root)
{
    for (int i = 0; i < 26; ++i)
        if (root->children[i] != nullptr)
            dfs (root->children[i]);
    if (root->suff_link != nullptr)
    f[root->suff_link->nr] = 1;
}

void dfs1 (trie *root)
{
    for (int i = 0; i < 26; ++i)
        if (root->children[i] != nullptr)
            dfs1 (root->children[i]);
    if (!f[root->nr])
        go_up(root);
}

void dfs2 (trie *root)
{
    if (root->isleaf)
        rez[root->index] = root->dp;
    for (int i = 0; i < 26; ++i)
        if (root->children[i] != nullptr)
            dfs2 (root->children[i]);
}

void solve (trie *root)
{
    for (auto it : s)
    {
        int ch = it - 'a';
        if (root->children[ch] != nullptr)
            root = root->children[ch], root->dp += 1;
        else
            root = suff(root, ch), root->dp += 1;
    }
}

int main()
{
    cin >> s >> n;
    for (int i = 1; i <= n; ++i)
    {
        cin >> a;
        ++poz;
        add_word(root, a);
    }
    bfs(root);
    solve(root);
    dfs (root);
    dfs1 (root);
    dfs2 (root);
    for (int i = 1; i <= n; ++i)
        cout << rez[i] << '\n';
    return 0;
}