Cod sursa(job #2282466)

Utilizator Dobricean_IoanDobricean Ionut Dobricean_Ioan Data 13 noiembrie 2018 19:45:32
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.99 kb
	
#include <fstream>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
 
using namespace std;
 
ifstream fin("ahocorasick.in");
ofstream fout ("ahocorasick.out");
 
const int SIGMA = 26;
 
 
struct Trie{
	
	int cnt;
	Trie *link;
	Trie *son[SIGMA];
	vector < int > words;
	Trie() {
		words.clear();
		link = NULL;
		cnt = 0;
		memset(son ,NULL,sizeof son);
	}
};
 
void addTrie(Trie *nod,int it, int cuv);
void BuildLinks();
 
Trie * root = new Trie();
Trie *cur ;
 
string a,aux;
vector < Trie*> nodlist;
int Sol[101];
 
int main() {
	
	fin >> a;
	int n;
	fin >> n;
	for ( int i = 1; i <= n; ++i) {
		aux.clear();
		fin >> aux;
		addTrie(root,0,i);
	}
	BuildLinks();
	cur = root;
	for ( int i = 0; i < a.size();++i) {
		while ( cur != root and ( cur -> son[a[i] -'a'] == NULL	) )
			cur =  cur->link;
			if ( cur -> son[a[i]-'a'] != NULL)
				cur = cur->son[a[i]-'a'];
			cur->cnt++;
		}
	for(int i = nodlist.size() - 1; i >= 0; i --) {
        Trie* node = nodlist[i];
        node -> link -> cnt += node -> cnt;
        for(auto it : node -> words) {
            Sol[it] += node -> cnt;
        }
    }
		for ( int i = 1; i <= n; ++i)
			fout << Sol[i] << "\n";
}
 
 
 
void addTrie(Trie *nod,int it, int cuv) {
	
	if ( it == aux.size() )
		nod->words.push_back(cuv);
	else {
		if ( nod ->son[aux[it]-'a'] == nullptr) nod->son[aux[it]-'a'] = new Trie();
			addTrie(nod->son[aux[it]-'a'],it+1,cuv);
	}
}
 
void BuildLinks() {
 
	queue< Trie* > Q;
	for ( int i = 0; i < SIGMA; ++i)
		if  ( root->son[i] != NULL) {
			root->son[i]->link = root;
			Q.push(root->son[i]);
		}
	while ( !Q.empty() ) {
		Trie *nod = Q.front();
		Q.pop();
		nodlist.push_back(nod);
		for ( int i = 0; i < SIGMA; ++i) 
			if ( nod ->son[i] != NULL) {
				Trie *linker = nod;
				do {
					linker = linker -> link;
				} while ( linker != root and ( linker->son[i] == NULL));
				if ( linker -> son[i] != NULL)
					linker = linker ->son[i];
				nod ->son[i] ->link = linker;
				Q.push(nod -> son[i]);
			}
	}
 
}