http://www.cnblogs.com/huangxincheng/archive/2012/12/02/2798317.html
http://www.cnblogs.com/Lyush/archive/2011/09/04/2165975.html
http://www.cnblogs.com/Booble/archive/2010/12/05/1897121.html
#include <queue>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define CLR(a,v) memset(a,v,sizeof(a))
namespace Trie
{
const int N = 1e6 + 5;
const int Size = 26;
int top;
struct Node{
Node *next[Size], *f;
int ended_cnt;
}node[N], *root;
inline Node* new_node()
{
node[top].ended_cnt = 0;
CLR(node[top].next,false);
return &node[top++];
}
void init()
{
top = 0;
root = new_node();
}
void insert(char *s)
{
Node *u = root;
for(int i=0;s[i];i++)
{
int id = s[i] - 'a';
if(u->next[id] == NULL)
u->next[id] = new_node();
u = u->next[id];
}
u->ended_cnt++;
}
}
namespace ACam
{
using namespace Trie;
void get_fail()
{
queue<Node*> Q;
for(int i=0;i<Size;i++)
{
Node *&ch = root->next[i];
if(!ch)
ch = root;
else
{
ch->f = root;
Q.push(ch);
}
}
while(!Q.empty())
{
Node *cur = Q.front();Q.pop();
for(int i=0;i<Size;i++)
{
Node *&ch = cur->next[i];
if(!ch)
ch = cur->f->next[i];
else
{
ch->f = cur->f->next[i];
Q.push(ch);
}
}
}
}
int match(char *s)
{
int ans = 0;
Node *u = root;
for(int i=0;s[i];i++)
{
int id = s[i] - 'a';
u = u->next[id];
Node *v = u;
while(v != root)
{
ans += v->ended_cnt;
v = v->f;
}
}
return ans;
}
}