建议加强数据
查看原帖
建议加强数据
194236
zhangqz楼主2023/8/19 17:17

先贴我队友的AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=200006,M=2000006;
int n,trie[M][26],f[M],last[M],ans[M],to[N],sta[N],top,cnt;
bool ed[M];
queue <int> que;
char s[N],t[M];
int main(){
	freopen("hack.in","r",stdin);
	freopen("ans.out","w",stdout);
	cin>>n;
	for (int i=1;i<=n;i++){
		cin>>s;
		int len=strlen(s),p=0;
		for (int j=0;j<len;j++){
			if (!trie[p][s[j]-'a']) trie[p][s[j]-'a']=++cnt;
			p=trie[p][s[j]-'a'];
		}
		ed[p]=1;
		to[i]=p;
	}
	cin>>t;
	for (int i=0;i<26;i++){
		int u=trie[0][i];
		if (u){	que.push(u);f[u]=0,last[u]=0;} 
	}
	while (!que.empty()){
		int h=que.front();
		for (int i=0;i<26;i++){
			int u=trie[h][i];
			if (!u){trie[h][i]=trie[f[h]][i];continue;} 
			que.push(u);
			f[u]=trie[f[h]][i];
			last[u]=ed[f[u]]>0?f[u]:last[f[u]];
		}
		que.pop();
	}
	int len=strlen(t),j=0;
	for (int i=0;i<len;i++){
		j=trie[j][t[i]-'a'];
		for (int e=j;e>0;e=last[e]) ans[e]++;
	}
	for (int i=1;i<=n;i++) cout<<ans[to[i]]<<endl;
	
	return 0;
}

其实是在暴力跳时只跳表示整个模式串的状态:

last[u]=ed[f[u]]>0?f[u]:last[f[u]];

但是在大量模式串是其中一个的后缀时,就会退化为暴力跳。

hack数据程序:

#include<bits/stdc++.h>
using namespace std;
int main(){
	freopen("hack.in","w",stdout);
	cout<<631<<endl;
	for(int i=1;i<=631;i++){
		for(int j=1;j<=i;j++) cout<<'a';
		cout<<endl;
	}
	for(int i=1;i<=2000000;i++){
		cout<<'a';
	}
	cout<<endl;
	return 0;
}
2023/8/19 17:17
加载中...