This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub tko919/library
#include "String/ahocorasick.hpp"
#pragma once #include "String/trie.hpp" template<int SZ,int start>struct AhoCorasick:Trie<SZ,start>{ using super=Trie<SZ,start>; using super::vs; vector<int> fail,bfs; void make_failure(){ fail.resize(vs.size()); queue<int> que; que.push(0); while(!que.empty()){ int v=que.front(); que.pop(); bfs.push_back(v); rep(c,0,SZ){ if(vs[v].nxt[c]==-1)continue; int to=vs[v].nxt[c]; que.push(to); if(v==0)continue; int f=fail[v]; while(f and vs[f].nxt[c]==-1)f=fail[f]; if(vs[f].nxt[c]!=-1)fail[to]=vs[f].nxt[c]; } } } void make_next(){ for(auto& v:bfs){ rep(c,0,SZ)if(vs[v].nxt[c]==-1){ vs[v].nxt[c]=vs[fail[v]].nxt[c]; if(vs[v].nxt[c]==-1)vs[v].nxt[c]=0; } } } void merge_id(){ for(auto& v:bfs)if(v>0){ rep(c,0,SZ){ int from=vs[fail[v]].nxt[c]; int to=vs[v].nxt[c]; if(from!=-1 and to!=-1){ for(auto& id:vs[from].ids)vs[to].ids.push_back(id); } } } } }; /** * @brief Aho-Corasick */
#line 2 "String/trie.hpp" template<int SZ,int start>struct Trie{ struct Node{ array<int,SZ> nxt; vector<int> ids; Node(){fill(ALL(nxt),-1);} }; vector<Node> vs; Trie(){vs.push_back(Node());} Node operator[](const int& i)const{return vs[i];} int move(int pos,char c){ return pos<0?-1:vs[pos].nxt[int(c-start)]; } void add(const string& s,int id){ int pos=0; for(auto& c:s){ int to=move(pos,c); if(to==-1){ to=vs.size(); vs.push_back(Node()); vs[pos].nxt[int(c-start)]=to; } pos=to; } vs[pos].ids.push_back(id); } int find(string& s){ int pos=0; for(auto& c:s){ pos=move(pos,c); if(pos==-1)return -1; } return pos; } }; /** * @brief Trie */ #line 3 "String/ahocorasick.hpp" template<int SZ,int start>struct AhoCorasick:Trie<SZ,start>{ using super=Trie<SZ,start>; using super::vs; vector<int> fail,bfs; void make_failure(){ fail.resize(vs.size()); queue<int> que; que.push(0); while(!que.empty()){ int v=que.front(); que.pop(); bfs.push_back(v); rep(c,0,SZ){ if(vs[v].nxt[c]==-1)continue; int to=vs[v].nxt[c]; que.push(to); if(v==0)continue; int f=fail[v]; while(f and vs[f].nxt[c]==-1)f=fail[f]; if(vs[f].nxt[c]!=-1)fail[to]=vs[f].nxt[c]; } } } void make_next(){ for(auto& v:bfs){ rep(c,0,SZ)if(vs[v].nxt[c]==-1){ vs[v].nxt[c]=vs[fail[v]].nxt[c]; if(vs[v].nxt[c]==-1)vs[v].nxt[c]=0; } } } void merge_id(){ for(auto& v:bfs)if(v>0){ rep(c,0,SZ){ int from=vs[fail[v]].nxt[c]; int to=vs[v].nxt[c]; if(from!=-1 and to!=-1){ for(auto& id:vs[from].ids)vs[to].ids.push_back(id); } } } } }; /** * @brief Aho-Corasick */