最长回文子串(LPS)Manacher(马拉车)算法--模板

manacher是高效处理回文子串的算法,不过因为只限求回文串,manacher的思想就是从左到右求出以每个位置为中心的最长字符串(由于回文串很明显的包含和对称性质,以同一位置为中心的字符串自然是包含在最长回文串里),利用回文串的对称性质,对每一个位置利用之前的信息来快速得到答案。近似于扫一遍,时间复杂度o(n),理解时最好对照代码,跑一遍程序。

p[ i ]:代表以i为中点的回文串长度。

mx:当前回文串的最右端点的位置。

id:当前最靠右端回文串的中点位置。

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
char str[N];
int p[N];
void manacher(char *s, int len)
{
    p[0] = 1;
    int id = 0, mx = 0;
    for(int i = 1; i < len; i++)
    {
        p[i] = mx > i ? min(p[id*2 - i],mx-i) : 1;
        
        while(str[i+p[i]] == str[i-p[i]])
            p[i]++;
        if(mx < p[i]+i)
        {
            id = i;
            mx = i + p[i];
        }
    }
}
int main()
{
    while(~scanf("%s",str))
    {
        int len = strlen(str);
        for(int i = len ; i >= 0; i--)
        {
            str[(i<<1)+1] = '#';
            str[(i<<1)+2] = str[i];
        }
        str[0] = '@';
        len = len * 2 + 2;
        manacher(str, len);
        int ans = 0;
        for(int i = 0; i < len; i++)
            ans = max(ans, p[i]-1);
        cout << ans << endl;
    }
}

猜你喜欢

转载自blog.csdn.net/sugarbliss/article/details/80731148