Manacher,不知道怎么进入提高级大纲的老登
下文的所有字符串,下标默认从
在字符串的开头结尾,以及两字符之间,插入一个符号 #,比如 manacher 字符串就变为 #m#a#n#a#c#h#e#r#。这样做是为了让两种回文子串的情况(长度为奇、偶)归并为一种,减少分类讨论。
Manacher 算法,可以在线性复杂度内,处理出
假设已经处理了
对于求
这个时候,对
- 若
i' 的回文区域在[L,R] 内,但左端没到L :
显然,
- 若
i 的回文区域的左端超过了L :
这个时候会发现,第
但此时以
- 若
i 的回文区域的左端正好是L :
这个时候不好判断,暴力扩展即可。
该算法流程完毕,感性理解可以得出复杂度为线性。
:::info[代码]
cin>>str,s="#";
for (auto i:str)
s+=i,s+='#';
n=s.size(),s=' '+s;
fo(i,1,n){
if (i>r) p[i]=1;
else p[i]=min(r-i,p[2*t-i]);
while (i+p[i]<=n&&i-p[i]>=1&&s[i+p[i]]==s[i-p[i]])
p[i]++;
if (p[i]+i>r)
r=i+p[i],t=i;
mx=max(mx,p[i]-1);
}
:::
图片出处:link。