Cod sursa(job #2338205)

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

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

ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
struct Node {
	int fv = 0;
	Node *fail = 0;
	Node *fi[sz] = {0};
} *root, *l[MAXN];
char c;
void insert(Node *n, int ind) {
	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);
}

stack< Node* > inv;
queue< Node* > q;

int main() {
	#ifdef BLAT
		freopen("input", "r", stdin);
		#define f cin
		#define g cout
	#else
    #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);
    }

    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->fi[i] && where != root) where = where->fail;
    		if(where->fi[i] && where->fi[i] != node->fi[i]) node->fi[i]->fail = where->fi[i];
    		else node->fi[i]->fail = root;
    		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;
}