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

  • 相关阅读:
    多线程的互斥(下)——信号量
    Linux下几种另类创建文件之方法
    Linux下VsFTP和ProFTP用户管理高级技巧 之一
    全面了解Linux下Proc文件系统
    许可证大阅兵
    SSH远程快速登录Linux
    为root账户更名
    Linux集群的I/O性能测试
    Think Pad笔记本分区解决思路及方法
    图形界面备份Linux系统介绍
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8462612.html
Copyright © 2020-2023  润新知