Cod sursa(job #2266481)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 22 octombrie 2018 18:25:45
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.34 kb

#include <bits/stdc++.h>



using namespace std;



const int MAXK = 100;

const int MAXN = 1000000;

const int MAXM = 10000;

const int SIGMA = 26;



struct Node {

  Node* fail;

  Node* son[SIGMA + 5];

  int fr;

  vector<int>word;



  Node() {

    fr = 0;

    fail = NULL;

    for (int i = 0; i < SIGMA; ++i)

      son[i] = NULL;

  }



  void add(char *s, int index) {

    if ('a' > *s || 'z' < *s) {

      word.push_back(index);

      return ;

    }

    int aux = *s - 'a';

    if (son[aux] == NULL)

      son[aux] = new Node;

    son[aux]->add(s + 1, index);

  }



  void get(char* s) {

    if ('a' > *s || 'z' < *s)

      return ;

    int aux = *s - 'a';

    if (son[aux] == NULL && fail != NULL)

      fail->get(s);

    else {

      if (son[aux] != NULL) {

        son[aux]->fr++;

        son[aux]->get(s + 1);

      } else {

        this->get(s + 1);

      }

    }

  }

};



char s[MAXN + 5];

char c[MAXN + 5];



int ans[MAXK + 5];



int main() {

  freopen("ahocorasick.in", "r", stdin);

  freopen("ahocorasick.out", "w", stdout);



  scanf("%s", s);

  int n;

  scanf("%d ", &n);

  Node* t = new Node;

  for (int i = 1; i <= n; ++i) {

    scanf("%s", c);

    t->add(c, i);

  }



  queue<Node*>q;

  vector<Node*>v;



  for (int i = 0; i < SIGMA; ++i)

    if (t->son[i] != NULL) {

      t->son[i]->fail = t;

      q.push(t->son[i]);

    }





  while (!q.empty()) {

    Node* aux = q.front();

    q.pop();

    v.push_back(aux);

    for (int i = 0; i < SIGMA; ++i) {

      if (aux->son[i] != NULL) {

        aux->son[i]->fail = aux;

        do {

          aux->son[i]->fail = aux->son[i]->fail->fail;

        } while (aux->son[i]->fail != t && aux->son[i]->fail->son[i] == NULL);

        if (aux->son[i]->fail->son[i] != NULL)

          aux->son[i]->fail = aux->son[i]->fail->son[i];

        q.push(aux->son[i]);

      }

    }

  }



  t->get(s);



  reverse(v.begin(), v.end());



  for (auto it:v) {

    Node* aux = it;

    aux->fail->fr += aux->fr;

    for (auto it1:aux->word)

      ans[it1] += aux->fr;

  }



  for (int i = 1; i <= n; ++i)

    printf("%d\n", ans[i]);



  return 0;

}