manacher算法

博客:

模版:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
const int maxn = 2e5 + 10;
char s[maxn], sNew[maxn<<1];
int p[maxn<<1], id, mx=0;
int L, R; //回文串在原串的左右端点位置

int Init()
{
    int len = strlen(s);
    sNew[0] = '$';
    sNew[1] = '#';
    int j = 2;
    for (int i = 0; i < len; i++){
        sNew[j++] = s[i];
        sNew[j++] = '#';
    }
    sNew[j] = '';
    return j;
}

int Manacher()
{
    int len = Init();
    int max_len = -1;
    mx = 0;
    for (int i = 1; i < len; i++){
        if (i < mx) p[i] = min(p[2 * id - i], mx - i);
        else p[i] = 1;

        ///在对象不是字符串时候,原本为了防止越界是左有'$'
        ///右有'',现在右边就没有'',需要人为填充替代!

        while (sNew[i - p[i]] == sNew[i + p[i]]) p[i]++;

        if (mx < i + p[i]){
            id = i;
            mx = i + p[i];
        }

        //max_len = max(max_len, p[i] - 1);

////      如果题目不要求输出回文串在原串的位置,则用下面代码更新答案
        if(max_len < p[i]){ ///这里L、R记录的是最长回文子串在原串的左右端点
            max_len = p[i];
            L = (i - p[i])>>1;
            R = (i + p[i] - 4)>>1; ///R = (i + p[i])/2 -2;
        }

    }
    return max_len;

///    最后如若需要找到的回文串则是
///    for(int i=(id-mx+1);i<=(id+mx-1);i++)
///         if(sNew[i]!='#'&&sNew[i]!='$') ///注意你设置的开头符号和填充符号,不同则需要修改
///             putchar(sNew[i]);
}
View Code
原文地址:https://www.cnblogs.com/linhaitai/p/9938604.html