HDU 2222 AC自动机

题意:

给出一些单词,和一段文本,输出文本中出现的单词个数,出现多次算一次。

 

模板题。

 

View Code
  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 
  7 #define N 1000010
  8 
  9 using namespace std;
 10 
 11 struct TR
 12 {
 13     int son[26],fail,bot;
 14 }tr[N];
 15 
 16 int n,len,q[N<<2],num,ans;
 17 bool vis[N];
 18 char s[N],str[N];
 19 
 20 inline void init()
 21 {
 22     for(int i=0;i<26;i++) tr[0].son[i]=-1;
 23     tr[0].bot=tr[0].fail=0;
 24     num=0;
 25 }
 26 
 27 inline void insert()
 28 {
 29     int now=0;
 30     len=strlen(s+1);
 31     for(int i=1;i<=len;i++)
 32     {
 33         if(tr[now].son[s[i]-'a']==-1)
 34         {
 35             num++;
 36             for(int j=0;j<26;j++) tr[num].son[j]=-1;
 37             tr[num].bot=tr[num].fail=0;
 38             tr[now].son[s[i]-'a']=num;
 39         }
 40         now=tr[now].son[s[i]-'a'];
 41     }
 42     tr[now].bot++;
 43 }
 44 
 45 inline void read()
 46 {
 47     init();
 48     ans=0;
 49     scanf("%d",&n);
 50     for(int i=1;i<=n;i++)
 51     {
 52         scanf("%s",s+1);
 53         insert();
 54     }
 55     for(int i=0;i<=num;i++) vis[i]=0;
 56     scanf("%s",str+1);
 57 }
 58 
 59 inline void bfs()
 60 {
 61     int h=1,t=2,now,to,tmp;
 62     q[1]=0;
 63     while(h<t)
 64     {
 65         now=q[h++];
 66         for(int i=0;i<26;i++)
 67             if(tr[now].son[i]!=-1)
 68             {
 69                 q[t++]=to=tr[now].son[i]; 
 70                 tmp=now;
 71                 while(tmp)
 72                 {
 73                     tmp=tr[tmp].fail;
 74                     if(tr[tmp].son[i]!=-1)
 75                     {
 76                         tr[to].fail=tr[tmp].son[i];
 77                         break;
 78                     }
 79                 }
 80             }
 81     }
 82 }
 83 
 84 inline void find(int x)
 85 {
 86     while(x&&!vis[x])
 87     {
 88         vis[x]=true;
 89         ans+=tr[x].bot;
 90         x=tr[x].fail;
 91     }
 92 }
 93 
 94 inline void ac_automation()
 95 {
 96     int now=0;
 97     len=strlen(str+1);
 98     for(int i=1;i<=len;i++)
 99     {
100         if(tr[now].son[str[i]-'a']!=-1)
101         {
102             now=tr[now].son[str[i]-'a'];
103             find(now);
104         }
105         else
106         {
107             int tmp=now;
108             while(now)
109             {
110                 now=tr[now].fail;
111                 if(tr[now].son[str[i]-'a']!=-1)
112                 {
113                     now=tr[now].son[str[i]-'a'];
114                     break;
115                 }
116             }
117             tr[tmp].son[str[i]-'a']=now;
118             find(now);
119         }
120     }
121 }
122 
123 inline void go()
124 {
125     bfs();
126     ac_automation();
127     printf("%d\n",ans);
128 }
129 
130 int main()
131 {
132     int cas; scanf("%d",&cas);
133     while(cas--) read(),go();
134     return 0;
135 }

 

 

posted @ 2013-02-18 21:33  proverbs  阅读(240)  评论(0编辑  收藏  举报