Cod sursa(job #3225398)

Utilizator hhhhhhhAndrei Boaca hhhhhhh Data 17 aprilie 2024 15:45:27
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
int go(int,int);
int getsuf(int);
string v;
int n,sol[105];
int where[105];
int grad[1000005];
struct node
{
    int lit;
    int par;
    int go[26];
    int suflink;
    int dictlink;
    int dp;
    int niv;
} emp;
int lg;
node t[1000005];
void put(node a)
{
    t[lg]=a;
    lg++;
}
void add(string s,int ind)
{
    int me=0;
    for(char c:s)
    {
        int lit=c-'a';
        if(t[me].go[lit]==-1)
        {
            t[me].go[lit]=lg;
            int x=lg;
            put(emp);
            t[x].par=me;
            t[x].lit=lit;
            t[x].niv=t[me].niv+1;
        }
        me=t[me].go[lit];
    }
    where[ind]=me;
}
int go(int me,int lit)
{
    if(t[me].go[lit]!=-1)
        return t[me].go[lit];
    if(me==0)
        return 0;
    t[me].go[lit]=go(getsuf(me),lit);
    return t[me].go[lit];
}
int getsuf(int me)
{
    if(t[me].suflink!=-1)
        return t[me].suflink;
    if(me==0||t[me].par==0)
    {
        t[me].suflink=0;
        return 0;
    }
    t[me].suflink=go(getsuf(t[me].par),t[me].lit);
    return t[me].suflink;
}
bool byniv(int a,int b)
{
    return t[a].niv>t[b].niv;
}
int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(0);
    emp.suflink=-1;
    emp.dictlink=-1;
    emp.niv=0;
    for(int i=0;i<26;i++)
        emp.go[i]=-1;
    put(emp);
    t[0].suflink=0;
    t[0].dictlink=0;
    fin>>v;
    fin>>n;
    for(int i=1;i<=n;i++)
    {
        string s;
        fin>>s;
        add(s,i);
    }
    int me=0;
    for(char c:v)
    {
        int lit=c-'a';
        me=go(me,lit);
        t[me].dp++;
    }
    for(int i=0;i<lg;i++)
        grad[getsuf(i)]++;
    queue<int> coada;
    for(int i=0;i<lg;i++)
        if(grad[i]==0)
            coada.push(i);
    while(!coada.empty())
    {
        int nod=coada.front();
        coada.pop();
        int x=getsuf(nod);
        t[x].dp+=t[nod].dp;
        grad[x]--;
        if(grad[x]==0)
            coada.push(x);
    }
    for(int i=1;i<=n;i++)
        fout<<t[where[i]].dp<<'\n';
    return 0;
}