From 0037aa862e3340ccf058d7ef710e7d8574ffb750 Mon Sep 17 00:00:00 2001 From: Ariel Date: Fri, 19 Jan 2024 18:21:06 +0800 Subject: [PATCH] Create ac-automaton.cc --- string/ac-automaton.cc | 86 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 string/ac-automaton.cc diff --git a/string/ac-automaton.cc b/string/ac-automaton.cc new file mode 100644 index 0000000..ecf9636 --- /dev/null +++ b/string/ac-automaton.cc @@ -0,0 +1,86 @@ +#include "../include.hh" + +void solve(vector ss, string t) { + int n = ss.size(); + vector> trie(1, vector(26)); + vector tag(1); + vector id(1); + vector alias(n, -1); + int last = 0; + // build trie for ss + for (int i = 0; i < n; ++i) { + auto&& s = ss[i]; + int curr = 0; + for (auto&& c : s) { + int x = c - 'a'; + if (!trie[curr][x]) + trie[curr][x] = ++last, + tag.push_back({}), + id.push_back({}), + trie.push_back(vector(26)); + curr = trie[curr][x]; + } + if (!tag[curr]) id[curr] = i; + else alias[i] = id[curr]; + tag[curr] = 1; + } + + + // build fail + vector fail(last + 1); + vector> suc(last + 1); + deque> dq; + for (int i = 0; i < 26; ++i) { + if (trie[0][i]) dq.emplace_back(trie[0][i], trie[0][i]), suc[0].push_back(trie[0][i]); + } + while (dq.size()) { + popfront(dq, c, rt); + for (int i = 0; i < 26; ++i) { + if (trie[c][i]) { + fail[trie[c][i]] = trie[fail[c]][i]; + suc[trie[fail[c]][i]].push_back(trie[c][i]); + dq.emplace_back(trie[c][i], rt); + } else { + trie[c][i] = trie[fail[c]][i]; + } + } + } + + + // match t + vector oc(last + 1); + int curr = 0; + for (auto&& c : t) { + int x = c - 'a'; + if (!trie[curr][x]) curr = fail[curr]; + curr = trie[curr][x]; + oc[curr] += 1; + } + + + // collect result + vector res(n); + auto dfs = [&] (auto dfs, int cur) -> int { + int cnt = oc[cur]; + for (auto&& c : suc[cur]) { + cnt += dfs(dfs, c); + } + if (cnt && tag[cur]) { + res[id[cur]] += cnt; + } + return cnt; + }; + dfs(dfs, 0); + for (int i = 0; i < n; ++i) { + if (alias[i] != -1) cout << res[alias[i]]; + else cout << res[i]; + cout << endl; + } +} + +int main() { + read(int, n); + readvec(string, ss, n); + read(string, t); + solve(ss, t); +}