diff --git a/contests/Cadernaveis/UVA10679_aho.cpp b/contests/Cadernaveis/UVA10679_aho.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e5e69c52bf64a1e737ae2f6d5c350d86e1e0f841 --- /dev/null +++ b/contests/Cadernaveis/UVA10679_aho.cpp @@ -0,0 +1,125 @@ +#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; +}