Cod sursa(job #2475537)

Utilizator lucametehauDart Monkey lucametehau Data 17 octombrie 2019 08:08:01
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 kb
#include <fstream>
#include <cstring>
#include <vector>

using namespace std;

ifstream cin ("ahocorasick.in");
ofstream cout ("ahocorasick.out");

struct Trie {
  vector <int> v;
  Trie *fail, *fiu[26];
  int cnt;
  Trie() {
    memset(fiu, 0, sizeof(fiu));
    v.clear();
    fail = NULL;
    cnt = 0;
  }
};

int n, l, r;

char s[1000005], t[10005];
int ap[10005];
Trie *trie, *trie2, *q[100000005]; // ????

void insert(Trie *trie, char *s, int ind) {
  if((*s) == NULL) {
    trie->v.push_back(ind);
    return;
  }
  if(!trie->fiu[(*s - 'a')])
    trie->fiu[(*s - 'a')] = new Trie;
  insert(trie->fiu[(*s - 'a')], s + 1, ind);
}

void bfs(Trie *trie) {
  Trie *tmp;
  l = 1, r = 1;
  q[l] = trie;
  trie->fail = trie;
  while(l <= r) {
    Trie *subTrie = q[l]; l++;
    for(int i = 0; i < 26; i++) {
      if(subTrie->fiu[i]) {
        tmp = subTrie->fail;
        while(tmp != trie && tmp->fiu[i] == NULL)
          tmp = tmp->fail;
        if(tmp->fiu[i] && tmp->fiu[i] != subTrie->fiu[i])
          tmp = tmp->fiu[i];
        subTrie->fiu[i]->fail = tmp;
        q[++r] = subTrie->fiu[i];
      }
    }
    // cout << l << " " << r << "\n";
  }
  trie->fail = NULL;
}

void antiBfs(Trie *trie) {
  for(int i = r; i; i--) {
    Trie *tmp = q[i];
    if(tmp->fail)
      tmp->fail->cnt += tmp->cnt;
    for(int j = 0; j < tmp->v.size(); j++)
      ap[tmp->v[j]] += tmp->cnt;
  }
}

int main() {
  cin >> s >> n;
  trie = new Trie;
  for(int i = 1; i <= n; i++) {
    cin >> t;
    insert(trie, t, i);
  }
  bfs(trie);
  // cout << "done\n";
  trie2 = trie;
  int m = strlen(s);
  for(int i = 0; i < m; i++) {
    int ch = s[i] - 'a';
    while(!trie2->fiu[ch] && trie2 != trie)
      trie2 = trie2->fail;
    if(trie2->fiu[ch])
      trie2 = trie2->fiu[ch];
    trie2->cnt++;
  }
  antiBfs(trie);
  for(int i = 1; i <= n; i++)
    cout << ap[i] << "\n";
  return 0;
}