AC自动机
作者:互联网
oj传送门
本质上是在trie树上套kmp的next数组(fail数组),用bfs按逐层遍历可以保证不重复和遗漏。
\\题目中要求出模式串重复次数,由于模式串自身较短,可以暴力失配找后缀匹配的模式串
#include<bits/stdc++.h>
using namespace std;
const int maxn=150*70+100;
const int maxm=1e6+100;
struct node{
int a[26];
int id;
int fail;
}ac[maxn];int tot;
string s;
string t[155];
int n,m;
inline void build_fail(){
queue<int>q;
ac[0].fail=0;
for(int i=0;i<26;i++){
if(ac[0].a[i]){
ac[ac[0].a[i]].fail=0;
q.push(ac[0].a[i]);
}
}
while(!q.empty()){
int u=q.front(),v;q.pop();
for(int i=0;i<26;i++){
if(ac[u].a[i]){
v=ac[u].fail;
while(v&&!ac[v].a[i])v=ac[v].fail;
if(ac[v].a[i])v=ac[v].a[i];
ac[ac[u].a[i]].fail=v;
q.push(ac[u].a[i]);
}
}
}
}
int ans[155];
void ac_query(){
int now=0;
for(auto r:s){
while(now&&!ac[now].a[r-'a'])
now=ac[now].fail;
if(ac[now].a[r-'a'])now=ac[now].a[r-'a'];
for(int t=now;t;t=ac[t].fail){
ans[ac[t].id]++;
}
}
}
signed main(){
// ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n&&n!=0){
for(int i=1;i<=n;i++)
cin>>t[i];
memset(ac,0,sizeof ac);tot=0;
for(int i=1;i<=n;i++){
int now=0;
for(auto r:t[i]){
if(!ac[now].a[r-'a'])
ac[now].a[r-'a']=++tot;
now=ac[now].a[r-'a'];
}
ac[now].id=i;
}
build_fail();
memset(ans,0,sizeof ans);
cin>>s;
ac_query();
vector<int>Ans;int mx=-1;
for(int i=1;i<=n;i++){
if(ans[i]>mx){
mx=ans[i];
Ans.clear();
Ans.push_back(i);
}
else if(ans[i]==mx){
Ans.push_back(i);
}
}
// printf("%d\n",mx);
cout<<mx<<endl;
for(auto r:Ans){
cout<<t[r]<<endl;
}
}
return 0;
}
标签:AC,int,ac,back,Ans,fail,自动机,mx 来源: https://www.cnblogs.com/xyc1719/p/16523105.html