This documentation is automatically generated by online-judge-tools/verification-helper
Trie木に対応するパターンマッチングオートマトンを構築する。
template<int W, int start>
class AhoCorasick {
public:
struct Node {
array<int, W> to;
int fail;
int val;
};
explicit AhoCorasick() : v(1) {}
vector<Node> v;
vector<int> ord;
int add(string &s, int cur = 0){
for (auto &&i : s) {
if(!v[cur].to[i-start]) v[cur].to[i-start] = v.size(), v.emplace_back();
cur = v[cur].to[i-start];
}
return cur;
}
void build() {
v[0].fail = -1;
int l = 0, r = 1;
ord.clear();
ord.reserve(v.size());
ord.emplace_back(0);
while(l < r){
int i = ord[l]; l++;
for (int c = 0; c < W; ++c) {
if(!v[i].to[c]) continue;
int to = v[i].to[c];
v[to].fail = (v[i].fail == -1 ? 0 : v[v[i].fail].to[c]);
ord.emplace_back(to);
r++;
}
if(i != 0){
for (int c = 0; c < W; ++c) {
if(!v[i].to[c]) v[i].to[c] = v[v[i].fail].to[c];
}
}
}
}
inline int next(int x, char c){ return v[x].to[c-start]; }
};
/**
* @brief Aho-Corasick法
* @docs _md/ahocorasick.md
*/
#line 1 "datastructure/ahocorasick.cpp"
template<int W, int start>
class AhoCorasick {
public:
struct Node {
array<int, W> to;
int fail;
int val;
};
explicit AhoCorasick() : v(1) {}
vector<Node> v;
vector<int> ord;
int add(string &s, int cur = 0){
for (auto &&i : s) {
if(!v[cur].to[i-start]) v[cur].to[i-start] = v.size(), v.emplace_back();
cur = v[cur].to[i-start];
}
return cur;
}
void build() {
v[0].fail = -1;
int l = 0, r = 1;
ord.clear();
ord.reserve(v.size());
ord.emplace_back(0);
while(l < r){
int i = ord[l]; l++;
for (int c = 0; c < W; ++c) {
if(!v[i].to[c]) continue;
int to = v[i].to[c];
v[to].fail = (v[i].fail == -1 ? 0 : v[v[i].fail].to[c]);
ord.emplace_back(to);
r++;
}
if(i != 0){
for (int c = 0; c < W; ++c) {
if(!v[i].to[c]) v[i].to[c] = v[v[i].fail].to[c];
}
}
}
}
inline int next(int x, char c){ return v[x].to[c-start]; }
};
/**
* @brief Aho-Corasick法
* @docs _md/ahocorasick.md
*/