Cod sursa(job #2137256)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 20 februarie 2018 18:09:23
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 kb
#include <bits/stdc++.h>
using namespace std;

ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");

struct node{
    node *next[26],*go[26];
    node *link,*F;
    int val;
    char lit;
    vector<int> cuv;

    node(node *_F, char _lit){
        memset(next,0,sizeof(next));
        memset(go,0,sizeof(go));
        link = 0;
        val = 0;
        F = _F;
        lit = _lit;
        cuv.clear();
    }
}*R;
int n;
vector<node*> H;
string s,c;

void add(string cuv,int x){
    node* it = R;
    for (auto c : cuv){
        if (!it->next[c-'a']) it->next[c-'a'] = new node(it,c);
        it = it->next[c-'a'];
    }
    (it->cuv).push_back(x);
}

node *getLink(node*);

node* GO(node *it,char c){
    if (it->next[c]) it->go[c] = it->next[c];
    if (it->go[c]) return it->go[c];
    if (!it->F) return it;
    it->go[c] = GO(getLink(it),c);
    return it->go[c];
}

node* getLink(node *it){
    if (!it->F) return it;
    if (!it->F->F) return it->F;
    if (it->link) return it->link;
    it->link = GO(getLink(it->F),it->lit-'a');
    return it->link;
}

int main()
{
    R = new node(0,0);
    R->link = R;
    f>>s;
    f>>n;
    for (int i=1;i<=n;i++){
        f>>c;
        add(c,i-1);
    }

    node* nod = R;
    for (auto it : s){
        nod = GO(nod,it-'a');
        nod->val++;
    }

    H.push_back(R);
    for (int i=0;i<H.size();i++){
        for (auto it : H[i]->next)
            if (it) H.push_back(it);
    }

    vector<int> ans;
    ans.resize(n);
    for (auto it = H.rbegin();it!=H.rend();it++){
        getLink(*it)->val += (*it)->val;
        for (auto cuv : (*it)->cuv) ans[cuv] += (*it)->val;
    }

    for (auto it : ans) g<<it<<'\n';

    return 0;
}