Cod sursa(job #2853343)

Utilizator hhhhhhhAndrei Boaca hhhhhhh Data 20 februarie 2022 10:48:09
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
string s;
int n;
int sol[105];
struct nod
{
    int lit=0;
    vector<int> isfin;
    int niv,cnt,par;
    int kid[31];
    int suflink=-1;
    int tran[31];
};
nod emp;
vector<nod> trie;
int getsuflink(int nod);
int gettran(int nod,int lit);
void addstring(string t,int ind)
{
    int poz=0;
    for(int i=0;i<t.size();i++)
    {
        int lit=t[i]-'a'+1;
        if(trie[poz].kid[lit]==-1)
        {
            nod x=emp;
            x.lit=lit;
            x.niv=trie[poz].niv+1;
            trie.push_back(x);
            int index=trie.size()-1;
            trie[poz].kid[lit]=index;
            trie[index].par=poz;
        }
        poz=trie[poz].kid[lit];
        if(i+1==t.size())
            trie[poz].isfin.push_back(ind);
    }
}
int getsuflink(int nod)
{
    if(trie[nod].suflink!=-1)
        return trie[nod].suflink;
    if(nod==0||trie[nod].par==0)
    {
        trie[nod].suflink=0;
        return 0;
    }
    int lit=trie[nod].lit;
    int par=trie[nod].par;
    trie[nod].suflink=gettran(getsuflink(par),lit);
    return trie[nod].suflink;
}
int gettran(int nod, int lit)
{
    if(trie[nod].tran[lit]!=-1)
        return trie[nod].tran[lit];
    if(trie[nod].kid[lit]!=-1)
    {
        trie[nod].tran[lit]=trie[nod].kid[lit];
        return trie[nod].tran[lit];
    }
    if(nod==0)
    {
        trie[nod].tran[lit]=0;
        return 0;
    }
    trie[nod].tran[lit]=gettran(getsuflink(nod),lit);
    return trie[nod].tran[lit];
}
bool comp(int a,int b)
{
    return trie[a].niv>trie[b].niv;
}
int main()
{
    fin>>s;
    fin>>n;
    for(int i=1;i<=26;i++)
        emp.kid[i]=emp.tran[i]=-1;
    trie.push_back(emp);
    for(int i=1;i<=n;i++)
    {
        string t;
        fin>>t;
        addstring(t,i);
    }
    for(int i=0;i<trie.size();i++)
    {
        getsuflink(i);
        for(int lit=1;lit<=26;lit++)
            gettran(i,lit);
    }
    int nod=0;
    for(int i=0;i<s.size();i++)
    {
        int lit=s[i]-'a'+1;
        nod=gettran(nod,lit);
        trie[nod].cnt++;
    }
    vector<int> vals;
    for(int i=0;i<trie.size();i++)
        vals.push_back(i);
    sort(vals.begin(),vals.end(),comp);
    for(int i:vals)
    {
        for(int j:trie[i].isfin)
            sol[j]+=trie[i].cnt;
        int nod=trie[i].suflink;
        trie[nod].cnt+=trie[i].cnt;
    }
    for(int i=1;i<=n;i++)
        fout<<sol[i]<<'\n';
    return 0;
}