manacher 学习笔记(再回首)
这一算法用于求最长回文子串。
思想上和 KMP 类似,都是利用已求出的部分去减少不必要的枚举。
我们设
我们又发现,上述过程只能针对长度为奇数的串。那如何处理偶数串呢?我们只需要在原串的缝隙间添上一些无用字符即可。
代码:
int n; int f[N*2]; char s[N*2], a[N]; int mx; void manacher() { s[0] = '!', s[1] = '#'; for(int i = 1; i<=n; i++) { s[i<<1] = a[i]; s[(i<<1)|1] = '#'; } n = (n<<1)|1, s[n+1] = '/'; for(int i = 1, mr = 1, mid = 0;i<=n; i++) { f[i] = i<mr?min(mr-i, f[mid*2-i]):1; while(s[i+f[i]]==s[i-f[i]]) f[i]++; if(i+f[i]>mr) mr = i+f[i], mid = i; } for(int i = 1; i<=n;i++) { mx = max(f[i]-1, mx); } }