Cod sursa(job #2137352)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 20 februarie 2018 19:02:02
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
 
const int N = 10005;
 
typedef struct node {
  int cnt;
  node *next[26], *link, *tata, *go[26];
  vector<int> cuv;
  char ch;
  node(node *_t = 0, char c = -1) {
    cuv.clear(); link = 0; cnt = 0; ch = c; tata = _t;
    memset(next, 0, sizeof(next));
    memset(go, 0, sizeof(go));
  }
}*Node;
 
int i, n, rs[N], st, dr;
char s[100 * N], c[N];
Node root = new node, it, q[100 * N];
 
void insert(int x) {
  Node it = root;
  for(int i = 0; c[i]; ++i) {
    if(!it->next[c[i] - 'a']) it->next[c[i] - 'a'] = new node(it, c[i] - 'a');
    it = it->next[c[i] - 'a'];
  }
  it->cuv.push_back(x);
}
 
Node go(Node it, char c);
 
Node getLink(Node it) {
  if(it->link) return it->link;
  if(!it->tata) return it->link = it;
  if(!it->tata->tata) return it->link = it->tata;
  return it->link = go(getLink(it->tata), it->ch);
}
 
Node go(Node it, char c) {
  if(it->go[c]) return it->go[c];
  if(it->next[c]) return it->go[c] = it->next[c];
  if(!it->tata) return it;
  return it->go[c] = go(getLink(it), c);
}
 
int main() {
  freopen("ahocorasick.in", "r", stdin);
  freopen("ahocorasick.out", "w", stdout);
  scanf("%s %d", s, &n);
  for(i = 1; i <= n; ++i) scanf(" %s", c), insert(i);
  for(it = root, i = 0; s[i]; ++i) it = go(it, s[i] - 'a'), ++it->cnt;
 
  for(q[st] = root; st <= dr; ++st)
    for(i = 0; i < 26; ++i)
      if(q[st]->next[i]) q[++dr] = q[st]->next[i];
 
  while(st--) {
    it = getLink(q[st]);
    if(it) it->cnt += q[st]->cnt;
    for(auto it : q[st]->cuv) rs[it] += q[st]->cnt;
  }
 
  for(i = 1; i <= n; ++i) printf("%d\n", rs[i]);
 
  return 0;
}