其他分享
首页 > 其他分享> > [JSOI2016]扭动的回文串

[JSOI2016]扭动的回文串

作者:互联网

清新结论配上巨大码量的哈希解法

思路:

第一种情况和第二种情况很容易解决,可以直接求一个正向哈希值在求一个反转后的哈希值,然后枚举回文中心,二分扩展了多少即可。

思考扭动的回文串应该满足那些特性,首先,一定是一段满足情况 \(1\) 或情况 \(2\) 的子串 \(S\),然后左边添加了一些,右边添加了一些,很明显,无论 \(S\) 是 \(A\) 的子串还是 \(B\) 的,左侧添加的都在 \(A\) 中,右侧的都在 \(B\) 中。

那么自然想到枚举所以满足条件的,但可惜的是,满足条件的 \(S\) 的个数是 \(n^2\) 级别的。

由于无论如何都无法在查找上进行优化,因为压根不可能全找出来,考虑观察一些性质,不妨假设 \(S\) 是以 \(l\) 为开始,\(r\) 为结尾,可以向两侧扩展的最长长度为 \(L\) ,若 \(k\) 为最大的满足 \(l\gets l-k\),\(r\gets r+k\) 为回文串的非负整数,则依然可以向两侧扩展 \(L-k\) 的长度,这个是显然的,所以对于一个确定的中心,当回文半径增长时,总长度不降,所以只需要检查以 \(i\) 为回文中心的最长回文串即可,当然这个结论其实还有很多其他的理解方式,比如:当半径增长时,其实是放宽了对向两侧扩展的那段字符串的限制,也可以解释这个总长度不减的结论。

实现就是找到以 \(i\) 为中心的最长的那个回文串,向两侧尝试扩展,然后打擂台比下长度,需要注意回文中心并不确认在那个字符串内,还可能是夹在两个字符中间,分讨即可。

一个简化分讨的技巧,解决回文中心在 \(B\) 串内其实就是相当于把 \(A\) 串和 \(B\) 串都反转再交换,然后跑中心在 \(A\) 中的代码。

代码:

两份代码思路上没区别,只不过第一份没有经过任何简化。

code1 3.60KB

code2 2.20KB

标签:JSOI2016,中心,两侧,扩展,扭动,添加,哈希,回文
来源: https://www.cnblogs.com/blogbyWHY/p/15858308.html