建议加强数据
查看原帖
建议加强数据
561253
nb_jzy楼主2024/12/16 19:04

我写了两种做法,AC 自动机的构建都是正确的,不过在对答案上传时的做法不同。

做法 1:只上传了字典树上自己的父亲。

做法 2:在 fail 树上上传 fail[u]

而显然,做法 1 是错的,但是洛谷的数据能过?HACK 很简单,见这篇讨论

贴个错误代码(洛谷可 AC):

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int n,num[maxn][26],cnt,fail[maxn],sum[maxn],idd[maxn];
int q[maxn*26],head,tail;
char s[maxn],t[maxn];
bool viss[maxn][26];
void add(){
	int len=strlen(s+1);
	int p=0;
	for(int i=1;i<=len;i++){
		int id=s[i]-'a';
		if(!num[p][id]){
			num[p][id]=++cnt;
		}
		p=num[p][id];
	}
	idd[p]++;
}
void buildAC(){
	head=0,tail=-1;
	for(int i=0;i<26;i++){
		if(num[0][i]){
			viss[0][i]=1;
			q[++tail]=num[0][i];
		}
	}
	while(head<=tail){
		int u=q[head++];
		for(int i=0;i<26;i++){
			if(num[u][i]){
				viss[u][i]=1;
				fail[num[u][i]]=num[fail[u]][i];
				q[++tail]=num[u][i];
			}
			else{
				num[u][i]=num[fail[u]][i];
			}
		}
	}
}
void dfs(int u){
	for(int i=0;i<26;i++){
		if(viss[u][i]){
			dfs(num[u][i]);
			sum[u]+=sum[num[u][i]];
		}
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",(s+1));
		add();
	}
	buildAC();
	scanf("%s",(t+1));
	int m=strlen(t+1);
	int p=0;
	for(int i=1;i<=m;i++){
		int id=t[i]-'a';
		p=num[p][id];
		sum[p]++; 
	}
	dfs(0);
	int ans=0;
	for(int i=0;i<=cnt;i++){
		if(sum[i]){
			ans+=idd[i];
		}
	}
	printf("%d",ans);
	return 0;
}
2024/12/16 19:04
加载中...