Cod sursa(job #2515239)

Utilizator mihai50000Mihai-Cristian Popescu mihai50000 Data 28 decembrie 2019 09:54:54
Problema Aho-Corasick Scor 100
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 1.95 kb
#include <bits/stdc++.h>

using namespace std;

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

const int SIGMA = 26;

vector <int> res;

struct Trie
{
	vector <int> ids;
	 
	int sum;
	 
	Trie* son[SIGMA];
	Trie* fail;
	 
	Trie()
	{
		ids.clear();
		 
		sum = 0;
		 
		for(int i = 0; i < SIGMA; i++)
			son[i] = nullptr;
			
		fail = nullptr;
	}
	 
	void add(string s, int id)
	{
		Trie* now = this;
		
		for(auto& i : s)
		{
			if(now -> son[i - 'a'] == nullptr)
				now -> son[i - 'a'] = new Trie();
		
			now = now -> son[i - 'a'];
		}
		
		now -> ids.push_back(id);
	}
	
	void make_fail(vector <Trie*> &q)
	{
		Trie* now = this;
		
		now -> fail = now;
		
		q.emplace_back(now);
		
		for(int i = 0; i < q.size(); i++)
		{
			now = q[i];
			
			for(int j = 0; j < SIGMA; j++)
				if(now -> son[j] != nullptr)
				{
					Trie* nod = now -> fail;
					Trie* fiu = now -> son[j];
					
					while(nod -> fail != nod && nod -> son[j] == nullptr)
						nod = nod -> fail;
					
					if(nod -> son[j] != nullptr && nod -> son[j] != fiu)
						nod = nod -> son[j];
					
					fiu -> fail = nod;
					
					q.emplace_back(fiu);
				}
		}
	}
	
	void tour(string s)
	{
		Trie* now = this;
		
		for(auto i : s)
		{
			while(now -> fail != now && now -> son[i - 'a'] == nullptr)
			{
				now = now -> fail;
			}
			
			if(now -> son[i - 'a'] != nullptr)
				now = now -> son[i - 'a'];
			
			now -> sum++;
		}
	}
	
	void bfs(vector <Trie*> q)
	{
		for(auto& i : q)
		{
			Trie* now = i;
			
			if(now -> fail != nullptr)
				now -> fail -> sum += now -> sum;
			
			for(auto& j : now -> ids)
				res[j] += now -> sum;
		}
	}
};

main()
{
	string v;
	fin >> v;
	
	int n;
	fin >> n;
	
	res.resize(n + 1);
	
	Trie *arb = new Trie();
	
	for(int i = 1; i <= n; i++)
	{
		string x;
		fin >> x;
		
		arb -> add(x, i);
	}
	
	vector <Trie*> q;
	
	arb -> make_fail(q);
	arb -> tour(v);
	
	reverse(q.begin(), q.end());
	
	arb -> bfs(q);
	
	for(int i = 1; i <= n; i++)
		fout << res[i] << '\n';
}