Advertisement
zipdang04

Aho-Corasick

Sep 29th, 2021
843
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.80 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. #define FOR(type, i, a, b) for(type i = (a); i <= (b); i++)
  6.  
  7. const int NaN = -1;
  8.  
  9. struct Node{
  10.     int parent, val;
  11.     int child[2] = {};
  12.    
  13.     int jmp;
  14.     int nxt[2] = {};
  15.  
  16.     int cnt;
  17.    
  18.     Node(int parent = NaN, int val = NaN): parent(parent), val(val){
  19.         jmp = 0, cnt = 0;
  20.         FOR(int, i, 0, 1) child[i] = NaN, nxt[i] = 0;
  21.     }
  22. };
  23.  
  24. struct Aho{
  25.     const int root = 0;
  26.     vector<Node> trie;
  27.     vector<string> str;
  28.     int trieLen = 0;
  29.    
  30.     bool empty(){
  31.         return trieLen == 0;
  32.     }
  33.  
  34.     void clear(){
  35.         trie.clear(); trieLen = 0;
  36.         str.clear();
  37.         trie.push_back(Node());
  38.     }
  39.  
  40.     Aho(){
  41.         clear();
  42.     }
  43.  
  44.     void addString(const string &s){
  45.         str.push_back(s);
  46.         int node = root;
  47.         for (char c: s){
  48.             c -= '0';
  49.             if (trie[node].child[c] == NaN){
  50.                 trie.push_back(Node(node, c)); trieLen++;
  51.                 trie[node].child[c] = trieLen;
  52.             }
  53.             node = trie[node].child[c];
  54.         }
  55.         trie[node].cnt++;
  56.     }
  57.  
  58.     void build(){
  59.         queue<int> q;
  60.         q.push(root);
  61.         while (!q.empty()){
  62.             int node = q.front(); q.pop();
  63.             int par = trie[node].parent;
  64.             int nodeVal = trie[node].val;
  65.  
  66.             if (par <= 0) trie[node].jmp = 0;
  67.             else {
  68.                 int jmp = trie[par].jmp;
  69.                 while (jmp > 0 && trie[jmp].child[nodeVal] == NaN)
  70.                     jmp = trie[jmp].jmp;
  71.                 if (trie[jmp].child[nodeVal] != NaN)
  72.                     jmp = trie[jmp].child[nodeVal];
  73.                 trie[node].jmp = jmp;
  74.             }
  75.  
  76.             FOR(int, val, 0, 1)
  77.                 if (trie[node].child[val] != NaN)
  78.                     trie[node].nxt[val] = trie[node].child[val];
  79.                 else
  80.                     trie[node].nxt[val] = trie[trie[node].jmp].nxt[val];
  81.  
  82.             if (node)
  83.                 trie[node].cnt += trie[trie[node].jmp].cnt;
  84.            
  85.             FOR(int, val, 0, 1) if (trie[node].child[val] != NaN)
  86.                 q.push(trie[node].child[val]);
  87.         }
  88.     }
  89.  
  90.     ll countMatch(const string &s){
  91.         int node = root;
  92.         ll answer = 0;
  93.         for (char c: s){
  94.             c -= '0';
  95.             node = trie[node].nxt[c];
  96.             answer += trie[node].cnt;
  97.         }
  98.         return answer;
  99.     }
  100. };
  101.  
  102. const int BIT = 20;
  103. Aho corasick[BIT + 1];
  104.  
  105. void add(const string &s){
  106.     int pos = 0; while (!corasick[pos].empty()) pos++;
  107.     corasick[pos].addString(s);
  108.  
  109.     FOR(int, i, 0, pos - 1){
  110.         for (string &s: corasick[i].str)
  111.             corasick[pos].addString(s);
  112.         corasick[i].clear();
  113.     }
  114.     corasick[pos].build();
  115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement