广义后缀自动机上基排的一个bug
众所周知
后缀自动机上按 mx 来一遍基数排序
就可以搞出 以个合法的拓扑序 就可以 在转移/parent上dp了
然而 在广义后缀自动机上 这样却未必合法
先给出一道广义后缀自动机裸题
BZOJ 3473: 字符串
给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串?
这个题的后缀自动机做法很简单
建个广义后缀自动机
每次加入一个串更新一下每个点的出现次数
具体来讲就是暴力跳parent 直到该点已被该串更新过
每个点x代表的串有 mx(x)-mx(Parent(x))个
一个点对答案的贡献就是parent tree上它所有祖先及他自己>=k的串的个数和
dfs一遍parent tree我们就可以更新完了
之后每个串跑一边转移 每到一个点都把贡献加上就做完了
但是在更新每个点贡献、最终计算答案的时候
我们并不只有一种方法
更新时
1) 可以傻傻的建一遍边
2) 也可以枚举每个点 递归搞父亲
3) 还可以搞一遍基数排序 之后dp
计算贡献时
(1) 可以老老实实跑一遍转移
(2) 但是也可以记录每个点会对哪个串有贡献 之后更新完直接加上
那么BJ所说的bug在哪里呢~
当我们采用 3) (2)的时候 就会GG啦
为了方便说明 先给一组傻傻的数据吧
2 234452345 //乱写个K就好嗄。。。
oog
og
把广义后缀自动机建出来
长这样
之后parent长这样
BJ在树上标了一个黑点一个红点
在parent上还标了他们的mx
发现了什么?
后缀自动机怎么多出了一个联通块
红黑两点的mx竟然相同
因为广义后缀自动机可能构建出多余的np
比如红点和那个转移到它的点 他们会为nq取代 比如黑点
又有的np即使没有nq也会和parent上父亲mx相等 比如 两个a
parent tree上父子mx可能相同
编号又具有不确定性
大多数时候父亲编号小于儿子
但父亲的编号可以比儿子大 试图以点标号为第二关键字将成为幻想
这样基排就不能得到合法的拓扑序
不过 用基排更新 跑转移统计还是可以的 因为鬼畜的点就不会有影响
就不能用每个标记的np来更新答案了
如果有神犇YY出解决办法一定要不吝赐教啊
之后这个bug就讲完啦
撒花