
#include<bits/stdc++.h>
#define ll long long
// Usage:
// AhoCorasick aho;
// aho.addString(s); (multiple-times)
// aho.compile();
// implement compute() method and use it.
struct AhoCorasick
{
static const int alphabet_size = 26;
struct Nodie {
int ch;
int pa;
int next[alphabet_size];
int leaf;
int link;
int go[alphabet_size];
// ==== more variables for specific problem
vector<int> end_here;
// ====
Nodie (int ch_ = '$', int pa_ = 0) {
ch = ch_;
pa = pa_;
fill(begin(next), end(next), -1);
leaf = 0;
link = -1;
fill(begin(go), end(go), -1);
// ==== init additional variables
// ====
}
};
vector<Nodie> trie;
AhoCorasick() {
trie.emplace_back();
}
void clear() {
trie.clear();
trie.emplace_back();
}
void addString(string s, int s_id) {
int u = 0; // 0 is root of trie
for (int i = 0; i < s.size(); ++i) {
int ch = s[i]-'a';
if (trie[u].next[ch] == -1) {
trie[u].next[ch] = trie.size();
trie.emplace_back(ch, u);
}
u = trie[u].next[ch];
}
trie[u].leaf++;
// ==== actions for specific problem
trie[u].end_here.emplace_back(s_id);
// ====
}
int getLink(int u) {
if (trie[u].link == -1) {
if (u == 0 || trie[u].pa == 0)
trie[u].link = 0;
else {
trie[u].link = getGo(getLink(trie[u].pa), trie[u].ch);
//==== actions for specific problem
getLink(trie[u].link);
trie[u].end_here.insert(trie[u].end_here.end(), trie[trie[u].link].end_here.begin(), trie[trie[u].link].end_here.end());
//====
}
}
return trie[u].link;
}
int getGo(int u, int ch) { // given node u and char ch.
// return node v so that trie[v].ch = ch and string-of-v[:-1] is longest suffix of u.
if (trie[u].go[ch] ==-1) {
if (trie[u].next[ch] != -1)
trie[u].go[ch] = trie[u].next[ch];
else
trie[u].go[ch] = (u == 0) ? 0 : getGo(getLink(u), ch);
}
return trie[u].go[ch];
}
void compile() {
for (int i = 1; i < trie.size(); ++i) {
getLink(i);
for (int j = 0; j < alphabet_size; ++j)
getGo(i, j);
}
}
//==== more functions for specific problem
void compute(string s, int *cnt) {
int u = 0;
for (int i = 0; i < s.size(); ++i) {
int ch = s[i] - 'a';
u = getGo(u, ch);
for (auto x : trie[u].end_here)
cnt[x]++;
}
}
//====
};
#include<bits/stdc++.h>
#define ll long long
// Usage:
// AhoCorasick aho;
// aho.addString(s); (multiple-times)
// aho.compile();
// implement compute() method and use it.
struct AhoCorasick
{
static const int alphabet_size = 26;
struct Nodie {
int ch;
int pa;
int next[alphabet_size];
int leaf;
int link;
int go[alphabet_size];
// ==== more variables for specific problem
vector<int> end_here;
// ====
Nodie (int ch_ = '$', int pa_ = 0) {
ch = ch_;
pa = pa_;
fill(begin(next), end(next), -1);
leaf = 0;
link = -1;
fill(begin(go), end(go), -1);
// ==== init additional variables
// ====
}
};
vector<Nodie> trie;
AhoCorasick() {
trie.emplace_back();
}
void clear() {
trie.clear();
trie.emplace_back();
}
void addString(string s, int s_id) {
int u = 0; // 0 is root of trie
for (int i = 0; i < s.size(); ++i) {
int ch = s[i]-'a';
if (trie[u].next[ch] == -1) {
trie[u].next[ch] = trie.size();
trie.emplace_back(ch, u);
}
u = trie[u].next[ch];
}
trie[u].leaf++;
// ==== actions for specific problem
trie[u].end_here.emplace_back(s_id);
// ====
}
int getLink(int u) {
if (trie[u].link == -1) {
if (u == 0 || trie[u].pa == 0)
trie[u].link = 0;
else {
trie[u].link = getGo(getLink(trie[u].pa), trie[u].ch);
//==== actions for specific problem
getLink(trie[u].link);
trie[u].end_here.insert(trie[u].end_here.end(), trie[trie[u].link].end_here.begin(), trie[trie[u].link].end_here.end());
//====
}
}
return trie[u].link;
}
int getGo(int u, int ch) { // given node u and char ch.
// return node v so that trie[v].ch = ch and string-of-v[:-1] is longest suffix of u.
if (trie[u].go[ch] ==-1) {
if (trie[u].next[ch] != -1)
trie[u].go[ch] = trie[u].next[ch];
else
trie[u].go[ch] = (u == 0) ? 0 : getGo(getLink(u), ch);
}
return trie[u].go[ch];
}
void compile() {
for (int i = 1; i < trie.size(); ++i) {
getLink(i);
for (int j = 0; j < alphabet_size; ++j)
getGo(i, j);
}
}
//==== more functions for specific problem
void compute(string s, int *cnt) {
int u = 0;
for (int i = 0; i < s.size(); ++i) {
int ch = s[i] - 'a';
u = getGo(u, ch);
for (auto x : trie[u].end_here)
cnt[x]++;
}
}
//====
};
#include<bits/stdc++.h> #define ll long long // Usage: // AhoCorasick aho; // aho.addString(s); (multiple-times) // aho.compile(); // implement compute() method and use it. struct AhoCorasick { static const int alphabet_size = 26; struct Nodie { int ch; int pa; int next[alphabet_size]; int leaf; int link; int go[alphabet_size]; // ==== more variables for specific problem vector<int> end_here; // ==== Nodie (int ch_ = '$', int pa_ = 0) { ch = ch_; pa = pa_; fill(begin(next), end(next), -1); leaf = 0; link = -1; fill(begin(go), end(go), -1); // ==== init additional variables // ==== } }; vector<Nodie> trie; AhoCorasick() { trie.emplace_back(); } void clear() { trie.clear(); trie.emplace_back(); } void addString(string s, int s_id) { int u = 0; // 0 is root of trie for (int i = 0; i < s.size(); ++i) { int ch = s[i]-'a'; if (trie[u].next[ch] == -1) { trie[u].next[ch] = trie.size(); trie.emplace_back(ch, u); } u = trie[u].next[ch]; } trie[u].leaf++; // ==== actions for specific problem trie[u].end_here.emplace_back(s_id); // ==== } int getLink(int u) { if (trie[u].link == -1) { if (u == 0 || trie[u].pa == 0) trie[u].link = 0; else { trie[u].link = getGo(getLink(trie[u].pa), trie[u].ch); //==== actions for specific problem getLink(trie[u].link); trie[u].end_here.insert(trie[u].end_here.end(), trie[trie[u].link].end_here.begin(), trie[trie[u].link].end_here.end()); //==== } } return trie[u].link; } int getGo(int u, int ch) { // given node u and char ch. // return node v so that trie[v].ch = ch and string-of-v[:-1] is longest suffix of u. if (trie[u].go[ch] ==-1) { if (trie[u].next[ch] != -1) trie[u].go[ch] = trie[u].next[ch]; else trie[u].go[ch] = (u == 0) ? 0 : getGo(getLink(u), ch); } return trie[u].go[ch]; } void compile() { for (int i = 1; i < trie.size(); ++i) { getLink(i); for (int j = 0; j < alphabet_size; ++j) getGo(i, j); } } //==== more functions for specific problem void compute(string s, int *cnt) { int u = 0; for (int i = 0; i < s.size(); ++i) { int ch = s[i] - 'a'; u = getGo(u, ch); for (auto x : trie[u].end_here) cnt[x]++; } } //==== };