Cod sursa(job #2270793)

Utilizator Dobricean_IoanDobricean Ionut Dobricean_Ioan Data 27 octombrie 2018 16:08:05
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.04 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;
}