Cod sursa(job #1508961)

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

using namespace std;

struct node {
    vector<int> term;
    unordered_map<char, int> leg;
    int bad, parent;
};
node T[1000005];
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);
}

int Node[1000005], Parent[1000005], b, e;
char Ch[1000005];
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 x : T[T[node].bad].term)
            T[node].term.push_back(x);
    }

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

char str[50000], se = 0;
void dump(int node) {
    cerr<<node<<"("<<str<<"): ";
    cerr<<"bad: "<<T[node].bad<<' '<<"sol: ";
    for(auto x : T[node].term) cout<<x<<" ";
    cout<<'\n';

    for(auto p : T[node].leg) {
        str[se++] = p.first;
        dump(p.second);
        str[--se] = 0;
    }
}

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(auto x : T[node].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;
    fin>>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;
}