Ac自动机!

Ac自动机!

写这篇blog时突然回想起我普及组的时光。

我还记得备考pj时,RQY跟我们说过,他和ZJ在QBXT学ac自动机

那时候我还十分天真的问,ac自动机是什么?

现在想想,那时候的自己还真是什么也不知道。

也算了解了我pj蒟蒻时的一个梦想了吧

一定能听见青春的乐章

原谅时间太晚了

解释还是明天在发吧

#include<cstdio> 
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
	int end;
	int fail;
	int ch[26];
};
node tree[1000100];
int tail;
char in[1000100];
void insert(char* data)
{
	int len=strlen(data);
	int now=0;
	for(int i=0;i<len;i++)
	{
		int nxt=data[i]-'a';
		if(tree[now].ch[nxt]==0)
			tree[now].ch[nxt]=++tail;
		now=tree[now].ch[nxt];
	}
	tree[now].end+=1;
	return ;
}
void get_fail()
{
	queue<int>q;
	for(int i=0;i<26;i++)
	if(tree[0].ch[i])
		{
			tree[tree[0].ch[i]].fail=0;
			q.push(tree[0].ch[i]);
		}
	while(!q.empty())
	{
		int pas=q.front();
		q.pop();
		for(int i=0;i<26;i++)
			if(tree[pas].ch[i])
			{
				tree[tree[pas].ch[i]].fail=tree[tree[pas].fail].ch[i];
				q.push(tree[pas].ch[i]);
			}	
			else
				tree[pas].ch[i]=tree[tree[pas].fail].ch[i];
	}
}
int query(char* data)
{
	int res=0;
	int now=0;
	int len=strlen(data);
	for(int i=0;i<len;i++)
	{
		now=tree[now].ch[data[i]-'a'];
		for(int j=now;j&&tree[j].end!=-1;j=tree[now].fail)
		{
			res+=tree[j].end;
			tree[j].end=-1;
		}
	}
	return res;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",in);
		insert(in);
	}
	get_fail();
	scanf("%s",in);
	printf("%d",query(in));
}
posted @ 2018-04-30 00:00  Lance1ot  阅读(135)  评论(0)    收藏  举报