首页 > 其他 > 详细

ac自动机

时间:2020-02-06 13:27:14      阅读:76      评论:0      收藏:0      [点我收藏+]

Input
第一行为一个整数n,表示文本的长度
第二行为一个长度为n的文本
第三行为一个整数m,表示模式串个数
下接m行,每行一个模式串
Output
共m行,若第i个模式串在文本中出现过则第i行输出YES,否则输出NO
数据范围
对于30%的数据,n<=10^3,m<=10^3;
对于80%的数据,n<=10^5,m<=10^4;
对于100%的数据,n<=10^5,m<=10^5。
输入文件大小不超过1M。
Sample Input
25
saintzeuscynthiathenahere
3
cynthia
hera
athena
Sample Output
YES
NO
YES

 

#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
struct Trie{
	int son[26];
	int cnt;
	int fail;
}AC[MAXN];
int n,m,tot=0,iidd[MAXN];
bool ans[MAXN];
char S[MAXN],T[MAXN];
void add(char *s,int len,int id){
	int now=0;
	for(register int i=0;i<len;i++){
		if(!AC[now].son[s[i]-‘a‘]) AC[now].son[s[i]-‘a‘]=++tot;
		now=AC[now].son[s[i]-‘a‘];
	}
	if(AC[now].cnt) iidd[id]=AC[now].cnt;
	else AC[now].cnt=id;
}
void get_fail(){
	queue<int> q;
	AC[0].fail=0;
	for(register int i=0;i<26;i++){
		if(AC[0].son[i]){
			AC[AC[0].son[i]].fail=0;
			q.push(AC[0].son[i]);	
		}
	}
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(register int i=0;i<26;i++)
		{
			if(AC[u].son[i])
			   {
				AC[AC[u].son[i]].fail=AC[AC[u].fail].son[i];
				q.push(AC[u].son[i]);	
			   }
			else 
			      AC[u].son[i]=AC[AC[u].fail].son[i];
		}
	}
}
void AC_query(char *s,int len){
	int now=0;
	for(register int i=0;i<len;i++)
	{
	 	now=AC[now].son[s[i]-‘a‘];
	 	for(register int t=now;t;t=AC[t].fail)
		 {
	 		if(AC[t].cnt&&ans[AC[t].cnt]) break;
	 		ans[AC[t].cnt]=true;
		}
	}
}
int main(){
	scanf("%d",&n);
	scanf("%s",S);
	scanf("%d",&m);
	for(register int i=1;i<=m;i++) iidd[i]=i;
	for(register int i=1;i<=m;i++){
		scanf("%s",T);
		add(T,strlen(T),i);
	} 
	get_fail();
	AC_query(S,n);
	for(register int i=1;i<=m;i++){
		if(ans[iidd[i]]) printf("YES\n");
		else printf("NO\n"); 
	}
	return 0;
}

  

ac自动机

原文:https://www.cnblogs.com/cutemush/p/12268210.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!