AC自動機 - 病毒侵襲持續中(HDU 3065)
阿新 • • 發佈:2018-12-30
Analysis
AC自動機板題
注意兩點:
1 多組資料(雖然題目沒有說)
2 文字串裡會有非大寫字母的字元,要注意判斷
Code
#include<bits/stdc++.h>
using namespace std;
char st[8000000],ch[2000][80];
int n,tot=1,ans[1009];
struct node{
int trans[26],fail,cnt,idx;
void init(){
fail=cnt=idx=0;
memset(trans,0,sizeof(trans));
}
}trie[ 2000*50];
inline void insert(int id){
int len=strlen(ch[id]),p=1;
for(int i=0;i<len;++i){
int c=ch[id][i]-'A';
if(!trie[p].trans[c]) trie[trie[p].trans[c]=++tot].init();
p=trie[p].trans[c];
}
trie[p].idx=id;
}
inline void buildfail(){
for(int i=0;i<26;++i) trie[0].trans[i]=1;
queue<int > q;q.push(1);
int v,w;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;++i){
v=trie[u].fail;
while(!trie[v].trans[i]) v=trie[v].fail;
v=trie[v].trans[i];w=trie[u].trans[i];
if(w) trie[w].fail=v,q.push(w);
else trie[u].trans[i]=v;
}
}
}
int main(){
while(scanf ("%d",&n)!=EOF)
{
trie[tot=1].init();
for(int i=1;i<=n;++i){
scanf("%s",ch[i]);
insert(i);
}
buildfail();
scanf("%s",st);
int tmp,len=strlen(st),now=1;
memset(ans,0,sizeof(ans));
for(int i=0;i<len;++i){
if(st[i]<'A'||st[i]>'Z') { now=1;continue; }
now=trie[now].trans[st[i]-'A'];
tmp=now;
while(tmp){
if(trie[tmp].idx) {
trie[tmp].cnt++;
ans[trie[tmp].idx]++;
}
tmp=trie[tmp].fail;
}
}
for(int i=1;i<=n;++i)
if(ans[i]) printf("%s: %d\n",ch[i],ans[i]);
}
return 0;
}