Cod sursa(job #3304074)

Utilizator unomMirel Costel unom Data 20 iulie 2025 12:27:18
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#include <fstream>
#include <vector>
#include <queue>
#include <iostream>
#include <cstring>

using namespace std;

struct node
{
    node *fii[26];
    node *fail;
    vector<int> output;
};

ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
int n;
string x;
char s[1000005];
node *root = new node();
int frec[105];

void adauga(string x, int ind)
{
    node *nod = root;

    for(auto it: x)
    {
        if(nod->fii[it - 'a'] == NULL)
        {
            nod->fii[it - 'a'] = new node();
        }

        nod = nod->fii[it - 'a'];
    }

    nod->output.push_back(ind);
}

void bfs()
{
    queue<node*> q;
    root->fail = root;
    for(int i = 0; i<26; i++)
    {
        if(root->fii[i] != NULL)
        {
            root->fii[i]->fail = root;
            q.push(root->fii[i]);
        }
    }

    while(!q.empty())
    {
        node *nod = q.front();
        q.pop();

        //cout<<"A";

        for(int i = 0; i<26; i++)
        {
            if(nod->fii[i] == NULL)
            {
                continue;
            }

            node *it = nod->fii[i];
            q.push(it);

            node *f = nod->fail;
            while(f != root && f->fii[i] == NULL)
            {
                f = f->fail;
            }

            if(f->fii[i] != NULL)
            {
                it->fail = f->fii[i];
            }
            else
            {
                it->fail = root;
            }

            for(auto ind: it->fail->output)
            {
                it->output.push_back(ind);
            }
        }
    }
}

int main()
{
    in>>s;

    in>>n;
    for(int i = 1; i<=n; i++)
    {
        in>>x;

        adauga(x, i);
    }

    bfs();

    int i = 0;
    node *nod = root;

    while(i < strlen(s))
    {
        if(nod->fii[s[i] - 'a'] != NULL)
        {
            nod = nod->fii[s[i] - 'a'];
            i++;

            for(auto it: nod->output)
            {
                frec[it]++;
            }
        }
        else
        {
            if(nod == root)
            {
                i++;
            }
            else
            {
                nod = nod->fail;
            }
        }
    }

    for(int i = 1; i<=n; i++)
    {
        out<<frec[i]<<'\n';
    }

    return 0;
}