码迷,mamicode.com
首页 > 其他好文 > 详细

AC自动机 板子

时间:2017-12-11 01:00:49      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:iostream   namespace   print   char s   efi   sha   class   自动   sharp   

https://www.luogu.org/problemnew/show/3808

在Tire上做KMP

#include<cstdio>
#include<queue>
#include<iostream>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
using std::cin;
const int N=4000011;
char s[N];
int tot,n,ans;
namespace AC_automaton{
	struct Tire{
		int cnt,fail;
		int to[27];
	}tr[N];
	inline void build_tire(){
		int u=0;
		for(register int i=0;s[i]!=‘\0‘;++i){
			if(!tr[u].to[s[i]-‘a‘])
				tr[u].to[s[i]-‘a‘]=++tot;
			u=tr[u].to[s[i]-‘a‘];
		}
		++tr[u].cnt;
	}
	inline void build_automaton(){		
		int v,u;
		std::queue<int>q;
		FOR(i,0,25)
			if((v=tr[0].to[i]))
				q.push(v);
		int now;
		while(!q.empty()){
			now=q.front();q.pop();
			FOR(i,0,25){
				v=tr[now].to[i];
				u=tr[now].fail;
				if(v){
					tr[v].fail=tr[u].to[i];
					q.push(v);
				}
				else
					tr[now].to[i]=tr[u].to[i];
			}
		}
	}
	inline void match(){
		int now=0,tmp;
		for(register int i=0;s[i]!=‘\0‘;++i){
			now=tr[now].to[s[i]-‘a‘];
			tmp=now;
			while(tmp&&tr[tmp].cnt!=-1){
				ans+=tr[tmp].cnt;
				tr[tmp].cnt=-1;
				tmp=tr[tmp].fail;
			}
		}
	}
}
using namespace AC_automaton;
int main(){
	scanf("%d\n",&n);
	while(n--){
		scanf("%s",s);
		build_tire();
	}
	tr[0].fail=0;
	build_automaton();	
	scanf("%s",s);
	match();
	printf("%d\n",ans);
	return 0;
}

  

AC自动机 板子

标签:iostream   namespace   print   char s   efi   sha   class   自动   sharp   

原文地址:http://www.cnblogs.com/Stump/p/8018715.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!