Skip to content
Snippets Groups Projects
Commit fcfc0d75 authored by Bruno Freitas Tissei's avatar Bruno Freitas Tissei
Browse files

Add 'I Love Strings' with Aho Corasick

parent 43eb105f
No related branches found
No related tags found
No related merge requests found
#include <bits/stdc++.h>
#define MAX 1010101
#define EPS 1e-6
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define fi first
#define se second
#define pb push_back
#define ende '\n'
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define mset(x, y) memset(&x, (y), sizeof(x))
using namespace std;
using ll = long long;
using ii = pair<int,int>;
struct AhoCorasick {
struct Node {
map<char,int> next;
int idx, fail, cnt, hei;
Node() : idx(-1), fail(0), cnt(0), hei(0) {}
int has(char i) { return next.count(i); }
int &operator[](char i) { return next[i]; }
};
vector<int> top;
vector<Node> trie;
AhoCorasick(const vector<string> &v) {
trie.pb(Node());
build(v);
top = preprocess();
}
int insert(const string &s) {
int n = 0;
for (int i = 0; i < s.size(); n = trie[n][s[i]], ++i)
if (!trie[n].has(s[i])) {
trie[n][s[i]] = trie.size();
trie.pb(Node());
}
return n;
}
void build(const vector<string> &v) {
for (int i = 0; i < v.size(); ++i) {
int n = insert(v[i]);
trie[n].idx = i;
}
preprocess();
}
inline int suffix(int v, char c) {
while (v != 0 && !trie[v].has(c)) v = trie[v].fail;
if (trie[v].has(c)) v = trie[v][c];
return v;
}
vector<int> preprocess() {
vector<int> Q = { 0 };
for (int i = 0; i != Q.size(); ++i) {
int u = Q[i];
for (auto j : trie[u].next) {
trie[j.se].fail = u ? suffix(trie[u].fail, j.fi) : trie[u].fail;
Q.pb(j.se);
}
}
return Q;
}
vector<int> match(const string &p) {
int u = 0;
for (auto i : p) {
u = suffix(u, i);
trie[u].cnt++;
}
for (int i = top.size() - 1; i >= 0; --i)
trie[trie[top[i]].fail].cnt += trie[top[i]].cnt;
vector<int> ans;
for (auto i : trie)
if (i.idx != -1 && i.cnt)
ans.pb(i.idx);
sort(all(ans));
return ans;
}
};
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t; cin >> t;
while (t--) {
string s; cin >> s;
int n; cin >> n;
vector<string> v(n);
for (auto &i : v) cin >> i;
AhoCorasick aho(v);
vector<int> ans = aho.match(s);
map<string,int> M;
for (int i = 0, j = 0; i < n; ++i) {
if (j < ans.size() && ans[j] == i) {
M[v[j]] = 1; ++j;
} else
if (!M[v[j]]) M[v[j]] = 0;
}
for (int i = 0; i < n; ++i)
cout << (M[v[i]] ? 'y' : 'n') << ende;
}
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment