Cod sursa(job #1784901)

Utilizator algebristulFilip Berila algebristul Data 20 octombrie 2016 17:18:03
Problema Aho-Corasick Scor 95
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <bits/stdc++.h>

using namespace std;

struct Trie {
  Trie* son[26];
  Trie* next;
  vector<Trie*> v;
  int cnt;

  Trie() {
    for (int i = 0; i < 26; i++) son[i] = 0;
    next = 0;
    cnt = 0;
  }
};

Trie* W[105];
Trie *T = new Trie;
char A[1000005];
char s[10005];
int n;

Trie* add(Trie *T, const char* str, int pos) {
  if (str[pos] == 0) {
    return T;
  }

  int c = str[pos] - 'a';
  if (T->son[c] == 0) {
    T->son[c] = new Trie;
  }

  return add(T->son[c], str, pos + 1);
}

void dfs(Trie *T) {
  for (int i = 0; i < T->v.size(); i++) {
    dfs(T->v[i]);
    T->cnt += T->v[i]->cnt;
  }
}

void backlinks() {
  queue<Trie*> Q;
  Q.push(T);

  while (!Q.empty()) {
    Trie* t = Q.front();
    Q.pop();
    for (int i = 0; i < 26; i++) {
      if (t->son[i] != 0) {
        Trie* aux = t->next;
        while (aux && aux->son[i] == 0)
          aux = aux->next;
        if (!aux) {
          t->son[i]->next = T;
          T->v.push_back(t->son[i]);
        } else {
          t->son[i]->next = aux->son[i];
          aux->son[i]->v.push_back(t->son[i]);
        }
        Q.push(t->son[i]);
      }
    }
  }
}

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

  cin >> A;
  cin >> n;

  for (int i = 1; i <= n; i++) {
    cin >> s;
    W[i] = add(T, s, 0);
  }

  backlinks();

  Trie* aux = T;
  for (int i = 0; A[i]; i++) {
    while (aux && !aux->son[A[i] - 'a'])
      aux = aux->next;

    if (!aux) {
      aux = T;
    } else {
      aux = aux->son[A[i] - 'a'];
      aux->cnt++;
    }
  }

  dfs(T);

  for (int i = 1; i <= n; i++) {
    cout << W[i]->cnt << '\n';
  }

  return 0;
}