AC自动机

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=26;
const int MAXN=500005;
struct Trie{
    int next[MAXN][N],fail[MAXN],end[MAXN];
    int root;
    int tot;
    int newnode()
    {
        for(int i=0;i<N;i++) next[tot][i]=-1;
        end[tot++]=0;
        return tot-1;
    }
    void init()
    {
		tot=0;
		root=newnode();
	}
	void insert(char s[])
	{
		int len=strlen(s);
		int now=root;
		for(int i=0;i<len;i++)
		{
			int k=s[i]-'a';
			if(next[now][k]==-1) next[now][k]=newnode();
			now=next[now][k];
		}
		end[now]++;
	}
	void build()
	{
		queue<int> que;
		fail[root]=root;
		for(int i=0;i<N;i++)
		    if(next[root][i]==-1) next[root][i]=root;
		    else
		    {
				fail[next[root][i]]=root;
				que.push(next[root][i]);
			}
		while(!que.empty())
		{
			int now=que.front();
			que.pop();
			for(int i=0;i<N;i++)
			    if(next[now][i]==-1) next[now][i]=next[fail[now]][i];
			    else
			    {
					fail[next[now][i]]=next[fail[now]][i];
					que.push(next[now][i]);
				}
		}
	}
	int query(char s[])
	{
		int len=strlen(s);
		int now=root;
		int res=0;
		for(int i=0;i<len;i++)
		{
			now=next[now][s[i]-'a'];
			int temp=now;
			while(temp!=root&&end[temp]!=-1)
			{
				res+=end[temp];
				end[temp]=-1;
				temp=fail[temp];
			}
		}
		return res;
	}
};
Trie ac;
char s[MAXN<<1];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n;
		scanf("%d",&n);
		ac.init();
		while(n--)
		{
			scanf("%s",s);
			ac.insert(s);
		}
		ac.build();
		scanf("%s",s);
		printf("%d\n",ac.query(s));
	}
	return 0;
}
posted @ 2020-05-02 11:07  study&work  阅读(82)  评论(0编辑  收藏  举报