Cod sursa(job #3149410)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 8 septembrie 2023 13:29:20
Problema Aho-Corasick Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.98 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

struct AhoCorasick {
	struct Node {
		int fail_link;
		map<char, int> link;
		int cnt;
		bool final;
		Node() {}
		Node(int fail_link, int cnt, bool final) : fail_link(fail_link), cnt(cnt), final(final) {}
	};
	const Node ROT = Node(-1, 0, false);
	vector<Node> T;
	vector<int> q;
	vector<int> order;
	int nodes = 1;
	AhoCorasick() {
		Init();
	}
	void Init() {
		T.clear();
		T.emplace_back(ROT);
	}
	// Adds a word to trie and returns the end node
	int Add(const string &s) {
		int node = 0, idx = 0;
		for(const auto &c : s) {
			idx++;
			auto &nxt = T[node].link[c];
			if(nxt == 0) {
				nxt = nodes++;
				if(idx == (int) s.size()) {
					T.emplace_back(Node(0, 0, true));
				} else {
					T.emplace_back(Node(0, 0, false));
				}
			}
			node = nxt;
		}
		return node;
	}
	// Advances from a node with a character (like an automaton)
	int Go(int node, char c) {
		while(node != -1 && !T[node].link.count(c)) {
			node = T[node].fail_link;
		}
		return (node == -1 ? 0 : T[node].link[c]);
	}
	// Builds links
	void Build() {
		T[0].fail_link = -1, q.push_back(0);
		for(int i = 0; i < (int)q.size(); ++i) {
			int node = q[i];
			order.emplace_back(node);
			for (auto [c, vec] : T[node].link) {
				T[vec].fail_link = Go(T[node].fail_link, c), q.push_back(vec);
			}
		}
	}
	void solve(const string &s) {
		int u = 0;
		for(const auto &it: s) {
			while(!T[u].link.count(it) && u) {
				u = T[u].fail_link;
			}
			if(T[u].link.count(it)) {
				u = T[u].link[it];
			}
			T[u].cnt += 1;
		}
		reverse(order.begin(), order.end());
		for(const auto &it: order) if(it != 0) {
			T[T[it].fail_link].cnt += T[it].cnt;
		}
		for(int i = 1; i < (int) T.size(); i++) {
			if(T[i].final) {
				fout << T[i].cnt << '\n';
			}
		}
	}
};

int main() {
	string s;
	fin >> s;
	int n;
	fin >> n;
	AhoCorasick ds;
	for(int i = 0; i < n; i++) {
		string t;
		fin >> t;
		ds.Add(t);
	}
	ds.Build();
	ds.solve(s);
	return 0;
}