Cod sursa(job #1508972)

Utilizator retrogradLucian Bicsi retrograd Data 23 octombrie 2015 12:29:20
Problema Aho-Corasick Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <fstream>
#include <vector>
#include <unordered_map>
#include <iostream>

using namespace std;

struct Nod {
    vector<int> term;
    unordered_map<char, int> leg;
    int bad, parent;
};
Nod T[200005];
int nodes, root;

int Count[60005];


void addWord(char str[], int ind) {
    int node = root;

    for(int i=0; str[i]; i++) {
        int &nw = T[node].leg[str[i]];
        if(nw == 0) nw = ++nodes;
        node = nw;
    }

    T[node].term.push_back(ind);
}

void make_links(int node, char pc, int parent) {
    if(node == root) {
       T[node].bad = -1;
    } else {
        int bad = T[parent].bad;
        while(bad != -1 && T[bad].leg.find(pc) == T[bad].leg.end())
            bad = T[bad].bad;

        T[node].bad = (bad == -1) ? root : T[bad].leg[pc];
    }

    for(auto p : T[node].leg) {
        make_links(p.second, p.first, node);
    }
}

void go(char Text[]) {
    int node = root;

    for(int i=0; Text[i]; i++) {
        while(node != -1 && T[node].leg.find(Text[i]) == T[node].leg.end())
            node = T[node].bad;

        if(node != -1) {
            node = T[node].leg[Text[i]];
            for(int t = node; t != -1; t = T[t].bad)
                for(auto x : T[t].term)
                    Count[x] ++;
        } else {
            node = root;
        }
    }
}

char Text[1000005], Pattern[50005];


int main() {
    ifstream fin("ahocorasick.in");
    ofstream fout("ahocorasick.out");

    int n;

    fin>>Text>>n;
    for(int i=1; i<=n; i++) {
        fin>>Pattern;
        addWord(Pattern, i);
    }

    make_links(root, 0, 0);

    go(Text);

    //dump(root);

    for(int i=1; i<=n; i++) {
        fout<<Count[i]<<'\n';
    }

    return 0;
}