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

回文自动机做题小结

时间:2020-06-12 12:26:51      阅读:45      评论:0      收藏:0      [点我收藏+]

标签:位置   数组   答案   span   子串   模板   删除   否则   字符   

模板

求以每个位置结尾的回文串的数量,加密输入

就是回文自动机节点的\(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\)树中子树的权值和

[CERC2014]Virus synthesis

每次可以加一个字符或加一个反串,求得到\(s\)的最少操作次数

按照双倍回文的套路求出\(trean\),设\(dp[x]\)是得到\(x\)点的最小操作次数,初始为\(len[x]\)

\[dp[x]=min\{dp[fa]+1,dp[tran[x]]+1+\frac{len[x]}{2}-len[tran[x]]\} \]

注意的是只在\(0\)的回文子树里操作,因为奇根子树里的回文串根本没法通过加反串得到

秩序魔咒

求在两个字符串里都出现的最长回文串和长度和数量

建两个回文树一起跑就行了

快乐的JYY

求两个字符串中,\(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\)节点需要的最小代价

\[dp[x]=min\{dis[x],dp[fail[x]]+E*(len[x]-len[fail[x]])\} \]

然后对于每个询问,在\(fail\)树上找到它最长回文后缀代表的节点,可以倍增实现,答案就是

\[dp[pos]+E*(r-l+1-len[pos]) \]

但是如果原串本身不是回文串,在跑\(dij\)的时候默认从原串的最大后缀回文开始跑的,还要再加一个\(A\)

回文自动机做题小结

标签:位置   数组   答案   span   子串   模板   删除   否则   字符   

原文地址:https://www.cnblogs.com/knife-rose/p/13098601.html

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