回文自动机做题小结
Posted knife-rose
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回文自动机做题小结相关的知识,希望对你有一定的参考价值。
求以每个位置结尾的回文串的数量,加密输入
就是回文自动机节点的(len)数组,对应的是最长回文后缀
求形如(AA^rAA^r)
方法一:建立(fail)树,然后对每个(len)是偶数的点,在子树内找有没有长度为(2*len)的点,通过打标记做到(O(n))
方法二:求一个与(fail)数组对应的(tran)数组,含义为长度不超过(frac{len}{2})的后缀回文串,如果(len[tran[x]]*2==len[x])说明该点可以选择
求法就是当(len[x]le 2)的时候(tran[x]=fail[x]),否则从父节点的(tran)开始沿着(fail)往上跳,直到找到能选且长度小于(frac{len}{2})的节点
求最大回文串的长度和出现的次数
长度不用说,考虑因为树上(fail)连接都是最大回文后缀,所以每个节点代表的回文串在原串中出现的次数就是(fail)树中子树的权值和
每次可以加一个字符或加一个反串,求得到(s)的最少操作次数
按照双倍回文的套路求出(trean),设(dp[x])是得到(x)点的最小操作次数,初始为(len[x])
注意的是只在(0)的回文子树里操作,因为奇根子树里的回文串根本没法通过加反串得到
求在两个字符串里都出现的最长回文串和长度和数量
建两个回文树一起跑就行了
求两个字符串中,(A)属于第一个串,(B)属于第二个串,(A=B)且是回文子串的对数
对两个回文树分别求出节点出现次数,然后一起跑,每个节点贡献乘起来
题目贼长但是蛮有意思的题
给定一个字符串,求通过操作变成某个子串的最小代价
操作一:把(S)变成(S)的最大回文后缀
操作二:把(S)变为(T)使得(S)是(T)的最大回文后缀,(T)是原串的子串(操作一的逆操作)
操作三:把一个回文串删除长度不超过(min(k,frac{len}{2}))的前缀和后缀
操作四:把一个回文串变成一个更长的回文串,变化后的回文串是原串的子串(操作三的逆操作)
操作五:在(S)前面加一个字符,使用后不能再用前四个操作
代价分别是(A,B,C,D,E)
挨个操作分析:
操作一:连边((i,fail[i],A))
操作二:连边((fail[i],i,B))
操作三:向自己回文树上的(1-k)级祖先连边,权值(C)
操作四:直接向自己子树连边边数就(O(n^2))了,考虑建立一个与原树对应的回文树,只能向子节点走,边权都是(0),然后再连边((i,i^{‘},D),(i^{‘},i,0))
跑(dij)求最短路(初始节点是最后的(pre))
设此时(dp[x])表示变化到(x)节点需要的最小代价
然后对于每个询问,在(fail)树上找到它最长回文后缀代表的节点,可以倍增实现,答案就是
但是如果原串本身不是回文串,在跑(dij)的时候默认从原串的最大后缀回文开始跑的,还要再加一个(A)
以上是关于回文自动机做题小结的主要内容,如果未能解决你的问题,请参考以下文章