AC自动机
本文共三道题目,都是 $ AC $ 自动机的模板题
1.Luogu P3808 【模板】AC自动机(简单版)
Code
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int N=1000005;
int n,rot,nxt[N],num[N],trie[N][26];
char pat[N],txt[N];
void insert(char s[])
{
int u=0,len=strlen(s+1);
for(int i=1;i<=len;i++)
{
int v=s[i]-'a';
if(!trie[u][v]) trie[u][v]=++rot;
u=trie[u][v];
}
num[u]++;
return;
}
void bfs()
{
queue<int> q;
for(int i=0;i<26;i++) if(trie[0][i]) q.push(trie[0][i]);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(trie[u][i])
{
nxt[trie[u][i]]=trie[nxt[u]][i];
q.push(trie[u][i]);
}
else trie[u][i]=trie[nxt[u]][i];
}
}
return;
}
int find(char s[])
{
int u=0,res=0,len=strlen(s+1);
for(int i=1;i<=len;i++)
{
int v=s[i]-'a';
for(int j=trie[u][v];j&&num[j]!=-1;j=nxt[j])
{
res+=num[j];
num[j]=-1;
}
u=trie[u][v];
}
return res;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>(pat+1);
insert(pat);
}
bfs();
cin>>(txt+1);
printf("%d\n",find(txt));
return 0;
}
2.Luogu P3796 【模板】AC自动机(加强版)
Code
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int N=15005;
int n,rot,ans,num[N],pos[N],trie[N][26],nxt[N];
char pat[155][N],txt[1000005];
void insert(char s[],int b)
{
int u=0,len=strlen(s+1);
for(int i=1;i<=len;i++)
{
int v=s[i]-'a';
if(!trie[u][v]) trie[u][v]=++rot;
u=trie[u][v];
}
pos[u]=b;
return;
}
void bfs()
{
queue<int> q;
for(int i=0;i<26;i++) if(trie[0][i]) q.push(trie[0][i]);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(trie[u][i])
{
nxt[trie[u][i]]=trie[nxt[u]][i];
q.push(trie[u][i]);
}
else trie[u][i]=trie[nxt[u]][i];
}
}
return;
}
void find(char s[])
{
int u=0,len=strlen(s+1);
for(int i=1;i<=len;i++)
{
int v=s[i]-'a';
for(int j=trie[u][v];j;j=nxt[j])
{
if(pos[j])
{
num[pos[j]]++;
ans=max(ans,num[pos[j]]);
}
}
u=trie[u][v];
}
return;
}
int main()
{
while(1)
{
scanf("%d",&n);
if(n==0) break;
rot=0;
memset(trie,0,sizeof(trie));
memset(pos,0,sizeof(pos));
for(int i=1;i<=n;i++)
{
cin>>(pat[i]+1);
insert(pat[i],i);
}
memset(nxt,0,sizeof(nxt));
bfs();
cin>>(txt+1);
ans=0;
memset(num,0,sizeof(num));
find(txt);
printf("%d\n",ans);
for(int i=1;i<=n;i++) if(num[i]==ans) cout<<(pat[i]+1)<<endl;
}
return 0;
}
3.Libre 10057 Keywords Search
Code
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int N=5e5+5;
int T,n,rot,nxt[N],num[N],trie[N][26];
char pat[55],txt[1000005];
void insert(char s[])
{
int u=0,len=strlen(s+1);
for(int i=1;i<=len;i++)
{
int v=s[i]-'a';
if(!trie[u][v]) trie[u][v]=++rot;
u=trie[u][v];
}
num[u]++;
return;
}
void bfs()
{
queue<int> q;
for(int i=0;i<26;i++) if(trie[0][i]) q.push(trie[0][i]);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(trie[u][i])
{
nxt[trie[u][i]]=trie[nxt[u]][i];
q.push(trie[u][i]);
}
else trie[u][i]=trie[nxt[u]][i];
}
}
return;
}
int find(char s[])
{
int u=0,res=0,len=strlen(s+1);
for(int i=1;i<=len;i++)
{
int v=s[i]-'a';
for(int j=trie[u][v];j&&num[j]!=-1;j=nxt[j])
{
res+=num[j];
num[j]=-1;
}
u=trie[u][v];
}
return res;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
rot=0;
memset(trie,0,sizeof(trie));
memset(num,0,sizeof(num));
for(int i=1;i<=n;i++)
{
cin>>(pat+1);
insert(pat);
}
memset(nxt,0,sizeof(nxt));
bfs();
cin>>(txt+1);
printf("%d\n",find(txt));
}
return 0;
}
Classical is something not fade,but grow more precious with time pass by,so is dream.梦想这东西和经典一样,永远不会因为时间而褪色,反而更显珍贵。