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 }

 

 

你可能感兴趣的:(AC自动机)