UVA1449 Dominating Patterns
阿新 • • 發佈:2019-04-11
algo namespace end ise size amp sin std att
思路
對所有模式串建AC自動機
在AC自動機上跑文本串,得出每個模式串的出現次數,輸出即可
AC自動機中的fail指針的意思是指向當前節點的最長的在Trie中存在和該最長後綴相等的前綴的節點
我的AC自動機寫法以0為根,0為中止條件
代碼
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; int Trie[12000][26],Nodecnt,root,fail[12000],isend[12000],cnt[12000],n,ans; char s[1001000],t[12000][100]; void insert(char *s,int len,int inq){ int o=root; for(int i=0;i<len;i++){ if(!Trie[o][s[i]-'a']) Trie[o][s[i]-'a']=++Nodecnt; o=Trie[o][s[i]-'a']; } isend[o]=inq; } queue<int> q; void build_AC(void){ for(int i=0;i<26;i++) if(Trie[root][i]){ fail[Trie[root][i]]=root; q.push(Trie[root][i]); } while(!q.empty()){ int x=q.front(); q.pop(); for(int i=0;i<26;i++){ if(Trie[x][i]){ fail[Trie[x][i]]=Trie[fail[x]][i]; q.push(Trie[x][i]); } else Trie[x][i]=Trie[fail[x]][i]; } } } void query(char *s,int len){ int o=root; for(int i=0;i<len;i++){ o=Trie[o][s[i]-'a']; int p=o; while(p){ if(isend[p]) cnt[isend[p]]++; p=fail[p]; } } } void init(void){ Nodecnt=0; root=0; memset(Trie,0,sizeof(Trie)); memset(fail,0,sizeof(fail)); memset(isend,0,sizeof(isend)); memset(cnt,0,sizeof(cnt)); ans=0; } int main(){ while(scanf("%d",&n)==1&&n){ init(); for(int i=1;i<=n;i++){ scanf("%s",t[i]); insert(t[i],strlen(t[i]),i); } build_AC(); scanf("%s",s); query(s,strlen(s)); for(int i=1;i<=n;i++) ans=max(ans,cnt[i]); printf("%d\n",ans); for(int i=1;i<=n;i++) if(cnt[i]==ans) printf("%s\n",t[i]); } return 0; }
UVA1449 Dominating Patterns