Cod sursa(job #2338189)

Utilizator LucaSeriSeritan Luca LucaSeri Data 7 februarie 2019 10:25:26
Problema Aho-Corasick Scor 25
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <bits/stdc++.h>
 
using namespace std;

const int MAXN = 110;
const int sz = 26;

struct Node {
	int fv;
	Node *fail = 0;
	Node *fi[sz];
	Node () {
		for(int i = 0; i < sz; ++i) fi[i] = 0;
	}
} *root, *l[MAXN];
char c;
void insert(Node *n, int ind, istream &f) {
	f.get(c);
	if(!isalpha(c)){
		l[ind] = n;
		return;
	}

	if(!n->fi[c-'a']) n->fi[c-'a'] = new Node();
	insert(n->fi[c-'a'], ind, f);
}

int main() {
	#ifdef BLAT
		freopen("input", "r", stdin);
		#define f cin
		#define g cout
	#else
		ifstream f("ahocorasick.in");
    	ofstream g("ahocorasick.out");
    #endif

    root = new Node();
    root -> fail = root;
    string s;
    f >> s;

    int n;
    f >> n;

    f.get();
    for(int i = 1; i <= n; ++i) {
    	insert(root, i, f);
    }

    stack< Node* > inv;
    queue< Node* > q;
    q.push(root);
    while(q.size()) {
    	Node *node = q.front();
    	q.pop();
    	inv.push(node);

    	for(int i = 0; i < sz; ++i) {
    		if(!node->fi[i]) continue;
    		Node *where = node->fail;
    		while(where != root && !where->fi[i]) where = where->fail;
    		if(where->fi[i] && where->fi[i] != node->fi[i]) where = where->fi[i];
    		else where = root;
    		node->fi[i]->fail = where;
    		q.push(node->fi[i]);
    	}
    }

    Node *node = root;
    for(int i = 0; i < s.size(); ++i) {
    	while(node != root && !node->fi[s[i] - 'a']) node = node->fail;
    	if(node->fi[s[i]-'a']) node = node->fi[s[i]-'a'];
    	node->fv ++;
    } 

    while(inv.size()) {
    	Node *cur = inv.top();
    	inv.pop();
    	cur->fail->fv += cur->fv;
    }

    for(int i = 1; i <= n; ++i) g << l[i]->fv << '\n';
    return 0;
}