1. 程式人生 > >AC自動機 - 病毒侵襲持續中(HDU 3065)

AC自動機 - 病毒侵襲持續中(HDU 3065)

傳送門

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; }