首页 > 代码库 > hdu2222 AC自动机入门

hdu2222 AC自动机入门

其实很久以来我都把sam当成ac自动机了

ac自动机的建立比sam简单多了

直接暴力建字典树,然后暴力跑fail就好了

(挖个坑:去学fail树)

裸题A一道,岂不美哉

 1 #include <bits/stdc++.h>
 2 #define MAX 1000000
 3 using namespace std;
 4 int T,n;char ch;
 5 struct acm
 6 {
 7     int cnt,h,t,c[MAX][26],fail[MAX],que[MAX],ret[MAX];
 8     void cl(int now)
 9     {
10         for(int i=0;i<26;i++)
11             c[now][i]=0;
12         ret[now]=0;
13     }
14     void clear()
15     {
16         cnt=1;
17         cl(1);
18     }
19     int ins(int now,int pa)
20     {
21         if(c[now][pa]) return c[now][pa];
22         else
23         {
24             c[now][pa]=++cnt;
25             cl(c[now][pa]);
26             return c[now][pa];
27         }
28     }
29     void mark(int now)
30     {
31         ++ret[now];
32     }
33     int go(int now,int pa)
34     {
35         if(c[now][pa]) return c[now][pa];
36         else return now>1?go(fail[now],pa):1;
37     }
38     void init()
39     {
40         for(fail[1]=que[1]=h=t=1;h<=t;h++)
41             for(int i=0;i<26;i++)
42                 if(c[que[h]][i])
43                 {
44                     int T;
45                     for(T=fail[que[h]];T>1 && !c[T][i];T=fail[T]);
46                     if((T==1 && !c[T][i])||(h==1)) fail[c[que[h]][i]]=1;
47                     else fail[c[que[h]][i]]=c[T][i];
48                     que[++t]=c[que[h]][i];
49                 }
50     }
51     int count(int now)
52     {
53         if(now==1 || ret[now]==-1) return 0;
54         int rt=count(fail[now])+ret[now];
55         ret[now]=-1;
56         return rt;
57     }
58 } a;
59 int main()
60 {
61     for(scanf("%d",&T);T;T--)
62     {
63         scanf("%d",&n);
64         a.clear();
65         for(int i=1;i<=n;i++)
66         {
67             for(ch=getchar();!isalpha(ch);ch=getchar());
68             int now=1;
69             for(;isalpha(ch);ch=getchar())
70                 now=a.ins(now,ch-a);
71             a.mark(now);
72         }
73         a.init();
74         int now=1,ans=0;
75         for(ch=getchar();!isalpha(ch);ch=getchar());
76         for(;isalpha(ch);ch=getchar())
77             now=a.go(now,ch-a),
78             ans+=a.count(now);
79         printf("%d\n",ans);
80     }
81     return 0;
82 }

 

hdu2222 AC自动机入门