题目来源由于之前我懒没写博客以至于花了大量时间来复健。
从后缀自动机起点开始,走出来的任何串都是原串后缀。从任何一个节点开始,走出来的串合起来就是所有子串。
一个后缀自动机上的结点指其endpos集合相同的一坨字符串。体现在从起点走到该点的所有串集合上。
我们假设一个变量maxlen为该集合的最长子串长度。
我直接说建造过程,就不管看不看得懂了。
首先,新建点u继承上一个点的信息,len+1;
其次,在满足没有儿子u的情况下,将上一个点跳fail,途径结点该儿子设为u
如果跳到了根节点,就结束了
反之,说明有点t有u儿子q。
如果该儿子q长度是t的+1,则合法,直接将u的fail设为q
反之,说名end集合不合法,新增克隆点tem。继承q的信息,将q和u的fail均设成tem,将tem的len设为t+1。
然后,t跳fail,将所有有u儿子的设为tem。完了
然后性质
反向fail树,子树size表示该点字符串出现次数。
任意结点代表end集合中没有长度相同的字符串,且字符串长度相邻递增。
也就是说我的len减去我fail的len可以得到我所代表的的子串数量。
ch形成dag(废话)
fail树上两点LCA表示最长公共后缀。(所以求最长公共前缀可以把串反向)
求第k大子串直接dag上动规。如果相同子串算不同次数也可以先fail树算贡献再动规。
bzoj4516/洛谷P4070 [Sdoi2016]生成魔咒
bzoj4566/洛谷3181 [Haoi2016]找相同字符