标签:
先说一下对后缀自动机的理解,主要是对构造过程的理解。
构造中,我们已经得到了前L个字符的后缀自动机,现在我们要得到L+1个字符的后缀自动机,什么需要改变呢?
首先,子串$[0,L+1)$对应的状态不存在,应当建立一个状态来表示这个串,显然,这个状态(np)的right集合是{L+1},max=L+1。
现在新建立了一个状态,我们还有两件事要干:找出能转移到这个状态的状态,建立链接;确定这个状态的min,即找到它在parent树上的父亲。
能转移到$np$的状态显然都是right集合包含L的状态,即p(子串$[0,L)$所在的状态)及p的祖先。
设c = s[L+1]我们沿着p往上爬,会遇到一些没有$c$的转移的状态,显然此时直接将c的转移连向它即可。
如果全都没有$c$的转移,那么np的父亲设为root,那么找到了np的min,即为1。
否则,现在我们到了第一个含有c的转移的状态,此时p代表红色部分的状态。
如上图,至少存在两个红色的部分,他们是相同的,且其中一个位置为L,另一个位置的下一个字符是c,(注意,红色线段以及蓝色线段的右端代表它的位置,左端代表位置减去$max$的地方)。设q=p->to[c],此时我们已经可以确定np的min了,就是p->max+2,即np的父亲的max应该为p->max+1。
这样,如果是图中的绿色状态,即q->max == p->max+1我们就可以宣布,找到了p的父亲。然后令p->par = q,这样在q以及所有的祖先的right集合中插入了L+1这个位置。
如果是蓝色状态,我们不得不考虑创建一个新的节点nq使它的max为p->max+1,来作为np的父亲,所以我们令, nq->max = p->max + 1, np->par = nq,这样之前提到的两个问题已经全部解决了,但是事实上我们需要在p->to[c]这个状态的right集合中插入L+1,所以我们令nq->par = q->par, q->par = nq,则nq这个状态表示right集合正是现在的p->to[c]需要的,接下来我们把p以及所有p的祖先中到q的转移全部换成q,这也要求nq和q具有相同的转移,需要memcpy(nq->to, q->to, sizeof(nq->to));
bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对广义后缀自动机的一些理解
标签:
原文地址:http://www.cnblogs.com/showson/p/5586134.html