AC自动机小结

 

一. 模板

 1 struct Trie
 2 {
 3     int sz, M[256];
 4     int next[MAXN][50], fail[MAXN], end[MAXN];
 5     int root, L, id // L为结点个数, id为单词个数。id可选择使用
 6     
 7     int newnode()
 8     {
 9         for(int i = 0; i<sz; i++)
10             next[L][i] = -1;
11         end[L++] = false;
12         return L-1;
13     }
14 
15     void init(int _sz)  
16     {
17         sz = _sz;
18         L = 0;
19         root = newnode();
20         for(int i = 0; i<26; i++)   //离散化
21             M['a'+i] = i;
22     }
23     
24     void insert(char buf[])
25     {
26         int len = strlen(buf);
27         int now = root;
28         for(int i = 0; i<len; i++)
29         {
30             if(next[now][M[buf[i]]] == -1) next[now][M[buf[i]]] = newnode();
31             now = next[now][M[buf[i]]];
32         }
33         end[now] = true;
34     }
35     void build()
36     {
37         queue<int>Q;
38         fail[root] = root;
39         for(int i = 0; i<sz; i++)
40         {
41             if(next[root][i] == -1) next[root][i] = root;
42             else fail[next[root][i]] = root, Q.push(next[root][i]);
43         }
44         while(!Q.empty())
45         {
46             int now = Q.front();
47             Q.pop();
48 //            end[now] |= end[fail[now]]; //此句视情况而选择
49             for(int i = 0; i<sz; i++)
50             {
51                 if(next[now][i] == -1) next[now][i] = next[fail[now]][i];
52                 else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]);
53             }
54         }
55     }
56 
57     int query(char buf[])   
58     {
59         int len = strlen(buf);
60         int now = root;
61         int res = 0;
62         for(int i = 0; i<len; i++)
63         {
64             now = next[now][M[buf[i]]];
65             int tmp = now;
66             while(tmp != root)
67             {
68                 res += end[tmp];
69                 end[tmp] = 0;
70                 tmp = fail[tmp];
71 
72             }
73         }
74         return res;
75 };
View Code

 

 

二. 题目类型

 

1.单纯的匹配:

HDU2222 Keywords Search (出现的单词种类数)
HDU2896 病毒侵袭(出现的单词种类及其出现次数)
HDU3065 病毒侵袭持续中
ZOJ3430 Detect the Virus(需要解码)
ZOJ3228 Searching the String(分可重叠和不可重叠统计)

 

2.字符串(不)含有单词的统计:

POJ2278 DNA Sequence(长度为n且不含单词的字符串个数)
HDU2243 考研路茫茫——单词情结(长度小于等于n且不含单词的字符串个数)
HDU2457 DNA repair(修改原串使其不含单词)
HDU4511 小明系列故事——女友的考验
POJ1625 Censored! (需要大数)

 

3.字符串含有特定个单词的统计:

HDU2825 Wireless Password

 

4.字符串含有所有type1单词且不含type2单词的统计:

HDU3247 Resource Archiver

 

5.字符串长度小于等于n且价值最大的统计:

HDU2296 Ring(需要输出字符串)

 

 

三. 对AC自动机的一些浅薄的理解

 

1.AC自动机的结构特点:

1)前缀性:由于AC自动机是以字典树为基础的,所以插入自动机里的单词,存在前缀重叠。

2)后缀性:这是由fail[]数组决定的,当当前位置匹配失败时,匹配的指针就自动跳到与当前字符串后缀匹配最大的那个状态。

 

2.AC自动机中状态之间的关系:

AC自动机中,每个结点都代表着一个状态。他们之间的关系构成了一张有向图。因此,当建立好自动机之后,就可以把状态之间的关系抽出来构成一张图,然后再根据这张图进行数据统计,如路径数、最短路径之类的。

 

posted on 2018-02-23 16:32  h_z_cong  阅读(288)  评论(0编辑  收藏  举报

导航