Cod sursa(job #2446672)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 10 august 2019 13:26:29
Problema Aho-Corasick Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.92 kb
#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

struct ac
{
        int sol;
        int id;
        ac *kids[26],*link;
        string word;
        bool bagat;

        ac()
        {
                bagat=0;
                sol=id=0;
                link=0;
                word="";
                for(int j=0;j<26;j++)
                        kids[j]=0;
        }

};

ac *root=new ac;

void baga(string s,int id)
{
 ///       cout<<":"<<s<<"\n";
        ac *now=root;
        for(auto &ch : s)
        {
                int c=ch-'a';
                if(now->kids[c]==0)
                {
                        now->kids[c]=new ac;
                        now->kids[c]->word=now->word;
                        now->kids[c]->word+=ch;
                }
                now=now->kids[c];
        }
        now->id=id;
}

void calc_link(ac *now)
{
    ///    cout<<now->word<<" "<<now->link->word<<"\n";
        for(int j=0;j<26;j++)
        {
                ac *nou=now->kids[j];
                if(nou)
                {
                        ac *t=now;
                        nou->link=root;
                        while(t!=root)
                        {
                                t=t->link;
                                if(t->kids[j])
                                {
                                        nou->link=t->kids[j];
                                        break;
                                }
                        }
                        calc_link(nou);
                }
        }
}

int ans[107];

int main()
{
        freopen("ahocorasick.in","r",stdin);
        freopen("ahocorasick.out","w",stdout);

        string pat;
        cin>>pat;
        int n;
        cin>>n;
        for(int j=0;j<n;j++)
        {
                string s;
                cin>>s;
                baga(s,j+1);
        }

        root->link=root;
        calc_link(root);

        ac *now=root;
        int pos=-1;
        for(auto &ch : pat)
        {
                pos++;
                int c=ch-'a';
                int cntroot=0;
                while(1)
                {
                        if(now->kids[c])
                        {
                                now=now->kids[c];
                                break;
                        }
                        else
                        {
                                if(now==root)
                                        break;
                                now=now->link;
                        }
                }
                ac *cur=now;
                while(cur!=root)
                {
                        ans[cur->id]++;
                        cur=cur->link;
                }
        }

        for(int j=1;j<=n;j++)
        {
                cout<<ans[j]<<"\n";
        }


        return 0;
}