Cod sursa(job #1495116)

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

using namespace std;

struct SuffixAutomaton {
    struct node {
        int link, len;
        int leg[30];
    };
    node T[200000];
    int last, nodes = 1;

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

    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[c-'a']; last = T[last].link) {
            T[last].leg[c-'a'] = cur;
        }

        if(last == -1) {
            T[cur].link = 0;
        } else {
            int q = T[last].leg[c-'a'];
            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;
                for(int c='a'; c<='z'; c++)
                    T[aux].leg[c-'a'] = T[q].leg[c-'a'];

                for(; last != -1 && T[last].leg[c-'a'] == q; last = T[last].link)
                    T[last].leg[c-'a'] = 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[c[i]-'a']) return 0;
            cur = T[cur].leg[c[i]-'a'];
        }
        return Count[cur];
    }
};
SuffixAutomaton A;

char text[1000001], pattern[100000];

int main() {

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

    cin>>text;
    for(int i=0; text[i]; i++)
        A.insert_char(text[i]);
    A.finish();

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

    return 0;
}