AC自动机 板子
在Trie上做KMP
https://www.luogu.org/problemnew/show/3808
#include<cstdio>
#include<queue>
#include<iostream>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
using std::cin;
const int N=4000011;
char s[N];
int tot,n,ans;
namespace AC_automaton{
struct Tire{
int cnt,fail;
int to[27];
}tr[N];
inline void build_tire(){
int u=0;
for(register int i=0;s[i]!='\0';++i){
if(!tr[u].to[s[i]-'a'])
tr[u].to[s[i]-'a']=++tot;
u=tr[u].to[s[i]-'a'];
}
++tr[u].cnt;
}
inline void build_automaton(){
int v,u;
std::queue<int>q;
FOR(i,0,25)
if((v=tr[0].to[i]))
q.push(v);
int now;
while(!q.empty()){
now=q.front();q.pop();
FOR(i,0,25){
v=tr[now].to[i];
u=tr[now].fail;
if(v){
tr[v].fail=tr[u].to[i];
q.push(v);
}
else
tr[now].to[i]=tr[u].to[i];
}
}
}
inline void match(){
int now=0,tmp;
for(register int i=0;s[i]!='\0';++i){
now=tr[now].to[s[i]-'a'];
tmp=now;
while(tmp&&tr[tmp].cnt!=-1){
ans+=tr[tmp].cnt;
tr[tmp].cnt=-1;
tmp=tr[tmp].fail;
}
}
}
}
using namespace AC_automaton;
int main(){
scanf("%d\n",&n);
while(n--){
scanf("%s",s);
build_tire();
}
tr[0].fail=0;
build_automaton();
scanf("%s",s);
match();
printf("%d\n",ans);
return 0;
}
https://www.luogu.org/problemnew/show/3796
#include<cstdio>
#include<queue>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
const int N=1000011;
std::queue<int>q;
namespace AC_automaton{
int ans[155];
char s[233][233];
char A[N];
struct Tire{
int fail;
int to[26];
int pos;
inline void init(){
fail=pos=0;
FOR(i,0,25)to[i]=0;
}
}tr[N];
int tot;
inline void insert(char *s,int pos){
int u=0,v;
for(register int i=0;s[i]!='\0';++i){
if(!tr[u].to[s[i]-'a'])
tr[tr[u].to[s[i]-'a']=++tot].init();
u=tr[u].to[s[i]-'a'];
}
tr[u].pos=pos;
}
inline void build_fail(){
int u,v,now;
FOR(i,0,25)
if((u=tr[0].to[i])){
tr[u].fail=0;
q.push(u);
}
while(!q.empty()){
now=q.front();q.pop();
FOR(i,0,25){
v=tr[now].to[i];
u=tr[now].fail;
if(v){
tr[v].fail=tr[u].to[i];
q.push(v);
}
else
tr[now].to[i]=tr[u].to[i];
}
}
}
inline void match(char *s){
int now=0,tmp;
for(register int i=0;s[i]!='\0';++i){
now=tr[now].to[s[i]-'a'];
tmp=now;
while(tmp){
++ans[tr[tmp].pos];
tmp=tr[tmp].fail;
}
}
}
}
using namespace AC_automaton;
int n,mx;
int main(){
while(~scanf("%d",&n)&&n){
FOR(i,0,n)
ans[i]=0;
tot=0;
tr[0].fail=0;
tr[0].init();
FOR(i,1,n){
scanf("%s",s[i]);
insert(s[i],i);
}
build_fail();
scanf("%s",A);
match(A);
ans[0]=0;
mx=1;
FOR(i,1,n)
if(ans[mx]<ans[i])
mx=i;
printf("%d\n",ans[mx]);
FOR(i,1,n)
if(ans[mx]==ans[i])
printf("%s\n",s[i]);
}
return 0;
}

浙公网安备 33010602011771号