洛谷P3796 【模板】AC自动机(加强版)

Code:

#include<cstdio>        //Aho Corasick Automaton
#include<cstring>
#include<queue>
using namespace std;
const int maxn=1000000+3;
const int maxd=20000+3;
const int sigma=30;
char S[maxn],A[160][80];
int mapp[152],times[maxd],val[maxd],last[maxd],f[maxd];
int cnt=0,ans;
queue<int>Q;
struct node{int next[30];}ch[maxd];
int idx(char a){return a-'a';}
struct V{
	void insert(char p[],int id){
		int n=strlen(p),cur=0;
		for(int i=0;i<n;++i){
			int u=idx(p[i]);
			if(!ch[cur].next[u])ch[cur].next[u]=++cnt;
			cur=ch[cur].next[u];
		}
		++val[cur],mapp[id]=cur;
	}
	void getfail(){
		 for(int i=0;i<sigma;++i)if(ch[0].next[i])Q.push(ch[0].next[i]);
		 while(!Q.empty()){
			int r=Q.front(); Q.pop();
			for(int i=0;i<sigma;++i){
				int u=ch[r].next[i];              
				if(!u){ch[r].next[i]=ch[f[r]].next[i];continue;}
				Q.push(u);int v=f[r];
				f[u]=ch[v].next[i];
				last[u]=val[f[u]]?f[u]:last[f[u]];
			}
		}
	}
	void print(int j){
	   if(j){
		if(val[j]){++times[j];ans=max(ans,times[j]);}
		if(last[j]){
			print(last[j]);
		}
	   }
	}
	void Automaton(char T[]){
		int n=strlen(T);int j=0;
		for(int i=0;i<n;++i){
			int c=idx(T[i]);
			j=ch[j].next[c];
			print(j);
		}
	}
}AC;
int main(){
	while(1){
		int n;scanf("%d",&n);if(!n)return 0;
		memset(ch,0,sizeof(ch)); 
		memset(val,0,sizeof(val));
		memset(last,0,sizeof(last));
		memset(f,0,sizeof(f));
		memset(times,0,sizeof(times));
		cnt=0,ans=0;
		for(int i=1;i<=n;++i){scanf("%s",A[i]);AC.insert(A[i],i);}
		scanf("%s",S);
		AC.getfail();
		AC.Automaton(S);
		printf("%d\n",ans);
		for(int i=1;i<=n;++i)
			if(times[mapp[i]]==ans)printf("%s\n",A[i]);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值