AC自动机【以下简称自动机】
我们写板子的时候会有三个数组:
tr{p,q} , fail[i] ,exist[i];
第一点,我们要弄清楚每一个变量名的具体意义。
AC自动机比其他的图板子多的就是:这是一个既有点又有边的图。我的意思不是点权和边权,而是他们的含义。
由于我们自动机的工作原理:是一个以trie树为底层的自动机。所以我们的每一个字母是建在边上的。为什么不把字母赋给点呢?这个曾经给我很大困惑,现在我认为是:
我们在查找一个单词是否在trie图上的时候,我们必须经过fail跳点。而且我们知道该图的基本用法就是,给定一个长串,找到哪几个字符在其中出现过。我们可以用O(n+m)的复杂度线性解决。这个的底层就是:我们在长串m的每一个字符之间加入了一个#(只是用这个代指间隔),我们每次匹配相当于从一个#越到下一个#,然后判断两个#之间的字符是否相匹配。如果匹配则继续。否则我们会找到最近的那一个匹配的#,也就是fail指针指向的位置,然后继续工作。但是怎么确定我们fail跳到的是哪一个点呢?这个好办,给每一个点加一个序号呗,按照插入的顺序。但是如果我们用点来作为字母的话,当我们跳到一个点的时候,我们如果再想要给这个点一个序号的话,就不好办了。这里自动机的节点起到了一个分配的作用,它综合了所有子节点。
所以,我们的三个数组的意义就是:从u点,经过字母i,到达的点用tr{u,i}来表示,这个其实很像我们的邻接表。然后fail也很显然,是从i点失配指向的点,exist则是判断该边是否存在。
//随时更新……
//如有错误,欢迎指正