「不会」后缀自动机

沿dag往下走是在末尾加字符
沿fail树往下走是在开头加字符
fail树上fa是最长后缀,是endpos集合最小扩充。

「弦论」
T=0时即是dag上dp
T=1是加上endpos集合大小的权,fail树预处理

「诸神眷顾的幻想乡」
广义后缀自动机,枚举叶子当根就能遍历所有序列

「公共串」
广义后缀自动机,匹配的过程中维护一个变量表示匹配的长度,
在sam节点上留下痕迹。

「差异」
fail树上lca代表lcs
于是可以把串reverse,把求lcp变成求lcs

「工艺」
复制一遍接在后面,建出sam
然后dag上贪心走字典序最小,走n步

「生成魔咒」
建边用map

「品酒大会」
看到lcs猜想可以fail树上dp,然后发现真的可以

「cheat」
首先要二分答案,但是只知道每个位置能匹配的最长长度,不知道在哪匹配最合适
所以上单调队列优化dp

「Substring」
既然强制在线了,那只能上LCT了
单点修改维护子树信息/链式修改不用维护信息

「你的名字」
这题好猛啊
考虑[1,|s|],则只需让T在S上跑匹配,同时找到T上符合条件的位置打标记
考虑[L,R],需要知道当前的后缀自动机中哪些部分在[L,R]是有意义的
考虑跑匹配时用到了哪些东西
1.trans[][26]数组
2.len[]用来更新目前最长匹配长度
3.fail[]用来失配跳转

然而我们发现fail数组直接使用最终的就可以,因为不会漏掉应该找到的最长后缀,
如果找到了区间中没有的最长后缀可以通过1.2.两项弄掉

然后考虑len数组,发现一个节点的len从他被初始化开始就不再变化,所以也不用管了
但是由于存在L的限制,导致它在被使用(更新目前最长匹配长度)时需要注意一个地方。
考虑一个endpos=P的节点i,若P-len[i]+1<L,则在点i的匹配长度不能到达len[i],而应是min(len[i],P-L+1)

最后考虑trans,能到达节点trans[i][j]的最低条件仍然为P[trans[i][j]]-len[trans[i][j]]+1>=L
最后发现问题集中到了我们要维护P
这个P是可以建完sam的最后,一发线段树合并解决的。

而我是个rz连线段树合并都不会。
线段树合并是,对于重复的节点,新开节点记录信息之和,否则直接改一下儿子就行了
千万别暴力遍历所有的节点...

posted @ 2019-12-26 11:42  Yxsplayxs  阅读(132)  评论(4编辑  收藏  举报