【模板】AC自动机(不同模板,不同难度)

**注意 query() 函数**

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n;
char s[N],t[N];

struct AC {
	int cnt,fail;
	int child[27];
}tr[N<<1]; int tot;

void build(char s[]) {
	int len=strlen(s+1);
	int u=0;
	for(int i=1;i<=len;i++) {
		if(!tr[u].child[s[i]-'a'+1]) {
			tr[u].child[s[i]-'a'+1]=++tot;
		}
		u=tr[u].child[s[i]-'a'+1];
	}
	tr[u].cnt++;
}

queue<int> que;
void getfail() {
	int u=0;
	for(int i=1;i<=26;i++) {
		if(tr[u].child[i]) {
			tr[tr[u].child[i]].fail=u;
			que.push(tr[u].child[i]);
		}
	}
	
	while(!que.empty()) {
		u=que.front(); que.pop();
		for(int i=1;i<=26;i++) {
			if(tr[u].child[i]) {
				tr[tr[u].child[i]].fail=tr[tr[u].fail].child[i];
				que.push(tr[u].child[i]);
			}
			else {
				tr[u].child[i]=tr[tr[u].fail].child[i];
			}
		}
	}
}

void query(char t[]) {// Warning !!!!!!!!!!!!!!!!!!!!!!
	int u=0;
	int len=strlen(t+1);
	int ans=0;
	for(int i=1;i<=len;i++) {
		u=tr[u].child[t[i]-'a'+1];
		for(int t=u;t&&tr[t].cnt;t=tr[t].fail) {
			ans+=tr[t].cnt;
			tr[t].cnt=0;
		}
	}
	printf("%d",ans);
}

int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("\n%s",s+1);
		build(s);
	}
	getfail();
	scanf("\n%s",t+1);
	query(t);
	return 0;
}
posted on 2024-11-28 12:06  Ueesugi_sakura  阅读(1)  评论(0编辑  收藏  举报