ACAutomaton.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // How many Pi are in T ?
  2. // COMPLEXITY: linear
  3. // USAGE: call init, insert to create dictionnary (strings are copied), and query
  4. const int MAXN = 500010;
  5. const int Alphabet = 26;
  6. struct Trie {
  7. int next[MAXN][Alphabet],fail[MAXN],end[MAXN];
  8. int root, L;
  9. int newnode() {
  10. for (int i=0; i<Alphabet; i++) next[L][i] = -1;
  11. end[L++] = 0;
  12. return L-1;
  13. }
  14. void init() {
  15. L=0;
  16. root = newnode();
  17. }
  18. void insert(const char buf[]) {
  19. int len = strlen(buf);
  20. int now = root;
  21. for (int i = 0; i < len; i++) {
  22. if (next[now][buf[i] - 'a'] == -1)
  23. next[now][buf[i] - 'a'] = newnode();
  24. now = next[now][buf[i] - 'a'];
  25. }
  26. end[now]++;
  27. }
  28. void build() {
  29. queue<int> Q;
  30. fail[root] = root;
  31. for (int i = 0; i < Alphabet; i++)
  32. if (next[root][i] == -1)
  33. next[root][i] = root;
  34. else {
  35. fail[next[root][i]] = root;
  36. Q.push(next[root][i]);
  37. }
  38. while(!Q.empty()) {
  39. int now = Q.front();
  40. Q.pop();
  41. for (int i = 0; i < Alphabet; i++)
  42. if (next[now][i] == -1)
  43. next[now][i] = next[fail[now]][i];
  44. else {
  45. fail[next[now][i]] = next[fail[now]][i];
  46. Q.push(next[now][i]);
  47. }
  48. }
  49. }
  50. int query(const char buf[]) {
  51. int len = strlen(buf);
  52. int now = root;
  53. int res = 0;
  54. for (int i = 0; i < len; i++) {
  55. now = next[now][buf[i] - 'a'];
  56. int temp = now;
  57. while (temp != root) {
  58. res += end[temp];
  59. end[temp] = 0;
  60. temp = fail[temp];
  61. }
  62. }
  63. return res;
  64. }
  65. };