HDU-2222 Keywords Search AC自动机模板

题意

给n个模式串,一个文本串,问文本串中出现了多少个模式串。

分析

AC自动机模板

Code

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
#define ll long long
using namespace std;
const int inf=1e9;
const int mod=1e9+7;
const int maxn=1e6+10;
int n;
char s[maxn];
struct ACtree{
	int son[maxn][26],cnt[maxn],fail[maxn],tot;
	int newnode(){
		for(int i=0;i<26;i++) son[tot][i]=0;
		cnt[tot++]=0;
		return tot-1;
	}
	void init(){
		tot=0;
		newnode();
	}
	void ins(char s[]){
		int rt=0,m=strlen(s);
		for(int i=0;i<m;i++){
			if(!son[rt][s[i]-'a']) son[rt][s[i]-'a']=newnode();
			rt=son[rt][s[i]-'a'];
		}
		cnt[rt]++;
	}
	void gao(){
		queue<int>q;
		for(int i=0;i<26;i++) if(son[0][i]) fail[son[0][i]]=0,q.push(son[0][i]);
		while(!q.empty()){
			int u=q.front();q.pop();
			for(int i=0;i<26;i++){
				if(son[u][i]){
					fail[son[u][i]]=son[fail[u]][i];
					q.push(son[u][i]);
				}else son[u][i]=son[fail[u]][i];
			}
		}
	}
	int qy(char s[]){
		int rt=0,m=strlen(s),ans=0;
		for(int i=0;i<m;i++){
			rt=son[rt][s[i]-'a'];
			for(int j=rt;j&&~cnt[j];j=fail[j]) ans+=cnt[j],cnt[j]=-1;
		}
		return ans;
	}

}AC;
int main(){
	//ios::sync_with_stdio(false);
	//freopen("in","r",stdin);
	int T;
	scanf("%d",&T);
	while(T--){
		AC.init();
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%s",s);
			AC.ins(s);
		}
		AC.gao();
		scanf("%s",s);
		printf("%d\n",AC.qy(s));
	}
	return 0;
}
posted @ 2019-09-25 15:28  xyq0220  阅读(97)  评论(0编辑  收藏  举报