码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对广义后缀自动机的一些理解

时间:2016-06-15 08:02:06      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:

先说一下对后缀自动机的理解,主要是对构造过程的理解。

构造中,我们已经得到了前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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!