Cod sursa(job #1495120)

Utilizator retrogradLucian Bicsi retrograd Data 2 octombrie 2015 17:17:27
Problema Aho-Corasick Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.18 kb
#include <iostream>
#include <unordered_map>
#include <vector>
#include <cstdio>

using namespace std;

struct SuffixAutomaton {
    #define NODES 300000

    struct node {
        int link, len;
        unordered_map<char, int> leg;
    };
    node T[NODES];
    int last, nodes = 1;

    int Count[NODES];
    vector<int> G[NODES];

    SuffixAutomaton() {
        last = 0; nodes = 0;
        T[0].link = -1;
        T[0].len = 0;
    }


    void insert_char(char c) {
        int cur = ++nodes;
        T[cur].len = T[last].len + 1;
        Count[cur] = 1;

        for(; last != -1 && !T[last].leg.count(c); last = T[last].link) {
            T[last].leg[c] = cur;
        }

        if(last == -1) {
            T[cur].link = 0;
        } else {
            int q = T[last].leg[c];
            if(T[q].len == T[last].len - 1) {
                T[cur].link = q;
            } else {
                int aux = ++nodes;
                T[aux].len = T[last].len + 1;
                T[aux].link = T[q].link;
                T[aux].leg = T[q].leg;

                for(; last != -1 && T[last].leg[c] == q; last = T[last].link)
                    T[last].leg[c] = aux;

                T[cur].link = T[q].link = aux;
            }
        }

        last = cur;
    }

    void finish() {
        for(int i=1; i<=nodes; i++) {
            G[T[i].link].push_back(i);
        }
        dfs(0);
    }

    void dfs(int node) {
        for(auto vec : G[node]) {
            dfs(vec);
            Count[node] += Count[vec];
        }
    }



    int getCount(const char *c) {
        int cur = 0;
        for(int i=0; c[i]; i++) {
            if(!T[cur].leg.count(c[i])) return 0;
            cur = T[cur].leg[c[i]];
        }
        return Count[cur];
    }
};
SuffixAutomaton A;

char pattern[10005];

int main() {

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

    for(char c = getchar(); isalpha(c); c = getchar())
        A.insert_char(c);
    A.finish();

    int q;

    cin>>q;
    while(q--) {
        cin>>pattern;
        cout<<A.getCount(pattern)<<'\n';
    }

    return 0;
}