Cod sursa(job #2341654)

Utilizator LucaSeriSeritan Luca LucaSeri Data 12 februarie 2019 08:43:52
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>

using namespace std;

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

const int sz = 26;
const int MAXN = 101;
char c;

struct nod{
    int nr;
    nod* link;
    nod* fii[sz];
    nod(){
        nr = 0;
        link = NULL;
        for(int i = 0; i < sz; ++i) fii[i] = NULL;
    }
}*root, *finish[MAXN];

void ins(nod* node, int ind){
    f.get(c);
    if(!isalpha(c)){
        finish[ind] = node;
        return;
    }
    if(node->fii[c-'a'] == NULL) node -> fii[c-'a'] = new nod();
    ins(node->fii[c-'a'], ind);
}

stack< nod* > invers;

void build_sufix_links(){
    queue< nod* > Q;
    root -> link = root;
    Q.push(root);
    while(Q.size()){
        nod* node = Q.front();
        Q.pop();
        invers.push(node);
        for(int i = 0; i < sz; ++i){
            if(node->fii[i] == NULL) continue;
            nod* where = node->link;
            while(where -> fii[i] == NULL && where != root) where = where -> link;
            if(where -> fii[i] != NULL && where -> fii[i] != node -> fii[i]) node -> fii[i] -> link = where->fii[i];
            else node->fii[i]->link = root;
            Q.push(node->fii[i]);
        }
    }
}

int main(){
    root = new nod();
    string s;
    f >> s;
    int n;
    f >> n;
    f.get();
    for(int i = 1; i <= n; ++i){
        ins(root, i);
    }
    build_sufix_links();

    nod* node = root;
    for(int i = 0; i < s.size(); ++i){
        while(node != root && node->fii[s[i]-'a'] == NULL) node = node->link;
        if(node->fii[s[i]-'a'] != NULL) node = node->fii[s[i]-'a'];
        node->nr ++;
    }
    while(invers.size()){
        nod* node = invers.top();
        invers.pop();
        node->link->nr += node->nr;
    }

    for(int i = 1; i <= n; ++i) g << finish[i]->nr << '\n';
    return 0;
}