Cod sursa(job #1571331)

Utilizator mikeshadowIon Complot mikeshadow Data 17 ianuarie 2016 21:32:44
Problema Aho-Corasick Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <bits/stdc++.h>

using namespace std;

struct Node;

typedef Node* LN;

struct Node
{
	map<char,LN> next;
	map<char,LN> bad;
    LN fail;
    LN prev;
    int c;

    int x;

    Node()
    {
    	x=0;
        next.clear();
        bad.clear();
        fail=0;
    }
};

LN root;

string s;
int n;
int id=0;
LN *po;

void addkey(LN t, int x)
{
    if (x==s.length())
        {
            po[id]=t;
            return;
        }
    if (!t->next[s[x]])
        t->next[s[x]] = new Node();

    (t->next[s[x]])->c = s[x];
    (t->next[s[x]])->prev = t;
    addkey(t->next[s[x]],x+1);
}

LN gf(LN t)
{
    if (t->fail) return t->fail;
    LN p;
    p = gf(t->prev);
    while (!p->next[ t->c ] && p!=root)
        p = gf(p);

    if (p->next[ t->c ]) t->fail = p->next[ t->c ];
    else t->fail = root;

    if (t->fail == t) t->fail = root;

    return t->fail;
}

LN gp(LN t, int c)
{
    if (t->next[c]) return t->next[c];
    if (t==root) return t->bad[c]=root;
    return t->bad[c] = gp(t->fail,c);
}

void genf(LN t)
{
    if (t==root) t->fail = root;
    t->fail = gf(t);
    for (auto i:t->next)
		if (i.second) genf(i.second);
}

void RDFS(LN t)
{
	for (auto i:t->next)
		if (i.second) RDFS(i.second);
	t->fail->x+=t->x;
}

void DFS()
{
    LN t = root;
    for (int i=0; i<s.length(); i++)
    {
        t = gp(t,s[i]);
        t->x++;
    }
}

int main()
{
	ifstream cin("ahocorasick.in");
	ofstream cout("ahocorasick.out");

    root = new Node();
    cin>>n;

	po = new LN[n];

    for (int i=0; i<n; i++)
    {
        cin>>s;
        id=i;
        addkey(root,0);
    }

    genf(root);

    cin>>s;
    DFS();
    RDFS(root);

    for (int i=0; i<n; i++)
    	cout<<po[i]->x<<'\n';

    return 0;
}