Cod sursa(job #2470501)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 9 octombrie 2019 12:19:52
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define lsb(x) (x & (-x)) 
    
using namespace std;

struct Aho {
	struct Node {
		Node *son[26], *fail;
		int cnt;
		vector <int> ids;
		Node() {
			memset(son, NULL, sizeof(son));
			fail = NULL, cnt = 0;
		}
	};

	Node *root = new Node;
	vector <Node*> Q;

	void add(Node *nod, string &str, int pos, int id) {
		if(pos == str.size()) {
			nod -> ids.push_back(id);
			return ;
		}
		char ch = str[pos] - 'a';
		if(nod -> son[ch] == NULL) {
			nod -> son[ch] = new Node;
		}
		add(nod -> son[ch], str, pos + 1, id);
	}
	inline void addWord(string &str, int id) {
		add(root, str, 0, id);
	}

	inline void bfs() {
		int p = 0;
		root -> fail = root;
		Q.push_back(root);
		while(p < Q.size()) {
			Node *nod = Q[p++];
			for(char ch = 0; ch < 26; ch++) {
				if(nod -> son[ch] == NULL) continue;
				Node *aux = nod -> fail;
				while(aux != root && aux -> son[ch] == NULL) {
					aux = aux -> fail;
				}
				if(aux -> son[ch] == NULL || aux == nod) {
					nod -> son[ch] -> fail = aux;
				}
				else {
					nod -> son[ch] -> fail = aux -> son[ch];
				}
				Q.push_back(nod -> son[ch]);
			}
		}
	}

	inline void solve(string &str) {
		Node *nod = root;
		for(auto &ch : str) {
			ch -= 'a';
			while(nod != root && nod -> son[ch] == NULL) {
				nod = nod -> fail;
			}
			if(nod -> son[ch] != NULL) nod = nod -> son[ch];
			nod -> cnt++;
		}
	}

	inline void antibfs(vector <int> &sol) {
		for(int i = Q.size() - 1; i >= 0; i--) {
			Node *nod = Q[i];
			for(auto it : nod -> ids) {
				sol[it] = nod -> cnt;
			}
			nod -> fail -> cnt += nod -> cnt;
		}
	}
};
   
int main() {
#if 1
    ifstream cin("ahocorasick.in");
    ofstream cout("ahocorasick.out");
#endif
    int i, n;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
	
	string str;
	cin >> str >> n;

	Aho aho;
	for(i = 0; i < n; i++) {
		string word;
		cin >> word;
		aho.addWord(word, i);
	}

	vector <int> sol(n);
	aho.bfs();
	aho.solve(str);
	//cerr << "!!\n";
	aho.antibfs(sol);

	for(i = 0; i < n; i++) {
		cout << sol[i] << "\n";
	}

	return 0;
}