Cod sursa(job #2193242)

Utilizator cella.florescuCella Florescu cella.florescu Data 9 aprilie 2018 14:14:05
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.18 kb
#include <bits/stdc++.h>

using namespace std;

const int SIGMA = 26;
const int MAXN = 1e2;
const int MAXL = 1e4;
const int MAXT = 1e6;

struct AhoNode {
  vector < int > words;
  int num_app;
  AhoNode *son[SIGMA], *fail;
  AhoNode () {
    num_app = 0;
    fail = NULL;
    for (int i = 0; i < SIGMA; ++i)
      son[i] = NULL;
  }
} *root = new AhoNode();

char text[MAXT + 1], word[MAXL + 1];
int ans[MAXN];

inline void add(AhoNode *node, char *s, int id) {
  if (*s == '\0') {
    node->words.push_back(id);
    return;
  }
  if (node->son[*s - 'a'] == NULL)
    node->son[*s - 'a'] = new AhoNode();
  add(node->son[*s - 'a'], s + 1, id);
}

vector < AhoNode* > q;

inline void construct_bfs() {
  q.push_back(root);
  root->fail = root;
  for (int i = 0; i < (int) q.size(); ++i) {
    AhoNode *node = q[i];
    for (int s = 0; s < SIGMA; ++s)
      if (node->son[s] != NULL) {
        AhoNode *fail_node = node->fail;
        while (fail_node != root && fail_node->son[s] == NULL)
          fail_node = fail_node->fail;
        if (fail_node->son[s] != NULL && fail_node->son[s] != node->son[s])
          fail_node = fail_node->son[s];
        node->son[s]->fail = fail_node;
        q.push_back(node->son[s]);
      }
  }
  root->fail = NULL;
}

inline void propag_bfs() {
  for (int i = (int) q.size() - 1; i >= 0; --i) {
    AhoNode *node = q[i];
    if (node->fail != NULL)
      node->fail->num_app += node->num_app;
    for (auto it : node->words)
      ans[it] = node->num_app;
  }
}

int main()
{
    int n;
    ifstream fin("ahocorasick.in");
    fin >> text >> n;
    for (int i = 0; i < n; ++i) {
      fin >> word;
      add(root, word, i);
    }
    fin.close();
    construct_bfs();
    AhoNode *curr = root;
    for (int i = 0; text[i] != '\0'; ++i) {
      int target = text[i] - 'a';
      while (curr != root && curr->son[target] == NULL)
        curr = curr->fail;
      if (curr->son[target] != NULL)
        curr = curr->son[target];
      ++curr->num_app;
    }
    propag_bfs();
    ofstream fout("ahocorasick.out");
    for (int i = 0; i < n; ++i)
      fout << ans[i] << '\n';
    fout.close();
    return 0;
}