两个处理回文串的利器。
马拉车可以求出每个字符为中心的最长回文串。
回文树可以统计本质不同的回文串数量以及每个回文串的个数,以下标i结尾的回文串个数。
马拉车
原理
首先在第一个位置插入一个’$’防止溢出,然后再所有字符之间插入’#’来处理奇偶回文串的问题。
大概原理就是如过当前回文串最右端包括了当前区间,那么就可以通过对称点得到一个初始值,如果不在初始值就为1。
然后暴力匹配即可。
最终算出的P数组代表以某个字符串为中心的半径,回文串的长度就是pi-1
时间啊复杂制度是O(n)的,因为每次暴力匹配只会匹配从未匹配的点。
代码
void manacher(char *s,int n)
{
int mx=0,id=0;
for(int i=1;i<=n;i++)
{
p[i]=(mx>i)?min(p[2*id-i],mx-i):1;
while(s[i-p[i]]==s[i+p[i]])p[i]++;
if(i+p[i]>mx)
{
mx=p[i]+i;
id<