hdu2222 AC自动机模板

本文深入解析AC自动机的原理及其实现过程,通过构建字典树并使用KMP算法进行模式匹配,介绍了如何预处理失败指针以提高搜索效率。文章详细展示了AC自动机在模式串匹配中的应用,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题:http://acm.hdu.edu.cn/showproblem.php?pid=2222

题解:AC自动机的本质是将模式串建成字典树跑kmp。首先新建字典树,bfs预处理失败指针,查找就可以。

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N=5e5+5;
int trie[N][26];
int mark[N],nxt[N],tot,cas,n;
char s[1000010];
queue<int> q;
inline void ins(char *s){//建字典树	
	int len=strlen(s+1);
	int p=1;
	for(int i=1,c;i<=len;i++){
		c=s[i]-'a';
		if(!trie[p][c]) {
			trie[p][c]=++tot;memset(trie[tot],0,sizeof trie[tot]); 
		}
		p=trie[p][c];
	}
	mark[p]++;
}
void bfs(){
	//fail指针 
	for(int i=0;i<26;i++) trie[0][i]=1;
	q.push(1);nxt[1]=0; 
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;i++){
			if(!trie[u][i]) trie[u][i]=trie[ nxt[u] ][i];	//小优化 
			else {
				q.push(trie[u][i]);
				int v=nxt[u];
				while(v>0 && !trie[v][i]) v=nxt[v];
				nxt[trie[u][i]]=trie[v][i];
			}	
		}
	} 
}
int query(char *s){
	int len=strlen(s+1);
	int p=1;int ans=0;
	for(int i=1,c,k;i<=len;i++){
		c=s[i]-'a';
		k=trie[p][c];
		while(k>1){
			ans+=mark[k];mark[k]=0; 	
			k=nxt[k];
		} 
		p=trie[p][c];
	}
	return ans;
} 

int main(){
//	freopen("hdu2222.in","r",stdin);
	scanf("%d",&cas);
	while(cas--){
		memset(mark,0,sizeof mark);
		for(int i=0;i<26;i++) trie[0][i]=1,trie[1][i]=0;		
		tot=1;
		scanf("%d",&n); 
		for(int i=1;i<=n;i++){
			scanf("%s",s+1);ins(s);
		} 
		bfs();
		scanf("%s",s+1);
		
		printf("%d\n",query(s));
	}
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值